Two Different JSON sources, Update at Different Ti

2020-05-06 02:41发布

问题:

I am trying to create a status list from two separate JSON sources. The list will display general info from the first source, and show a status color based on the number of people in the second source.

The first source contains general data that will not be changing much (i.e. feed name, version, description) and likely called only two times a day. See code example below:

/metadata

{
    data: [
        {
            "feedName": "Feed 1", 
            "version": "000001", 
            "location": "1234 Main Street, New York, New York" 
            "description": "This feed gives information on the number of people in Building A at a given time."
        }, 
        {
            "feedName": "Feed 2", 
            "version": "000001", 
            "location": "1000 Broad Street, New York, New York" 
            "description": "This feed gives information on the number of people in Building B at a given time."
        }, 
        {
            "feedName": "Feed 3", 
            "version": "000001", 
            "location": "1111 Governor Street, New York, New York" 
            "description": "This feed gives information on the number of people in Building C at a given time."
        }
    ]
} 

The second source contains data on each feed that will change very often. This source will be called more frequently; about every hour.

/customers

{
    data: [
        {
            "metricName": "Feed 1", 
            "customerNumber": "10", 
            "time": "2012-10-03 15:30:00"

        }, 
        {
            "metricName": "Feed 2", 
            "customerNumber": "5", 
            "time": "2012-10-03 15:30:00"
        }, 
        {
            "metricName": "Feed 3", 
            "customerNumber": "15", 
            "time": "2012-10-03 15:30:00"
        }
    ]
} 

Where metricName and feedName are actually the same values.

I've only dealt with one JSON source per list before, where my Javascript would look like this:

$scope.metadataList = function(){
    $http.get('/metadata')
        .then(function(result) {
            $scope.metadata = result.data.data; 
        }); 
}

and corresponding HTML would look like this:

<ul ng-repeat = "data in metadata | orderBy: ['feedName']">
    <li> {{data.feedName}}, {{data.version}} </li>
</ul>

So my question is, how to I make async calls to each data source? How do I match them up to populate my list with both the metadata information and the customer information?

Update Before anyone asks, I did try ng-repeat = "data in metadata.concat(customers)" where "customers" defines the second data source, (as shown in Ng-repeat datas from 2 json Angular) but that only appends to the end of the list ... not quite what I was going for.

Thank you in advance.

回答1:

First, you can call the all() method from the $q service to resolve multiple promises, in that case the two requests.

// both promises calling your api to get the jsons
var promises = {
  metadataPromise: $http.get('/echo/json/', {}),
  customersPromise: $http.get('/echo/json/', {})
};

$q.all(promises).then(function(response) {
  metadata = response.metadataPromise;
  customers = response.customersPromise;

  joinMetadataAndCustomers();
}, function(response) {
  // in case any promise is rejected
});

After that, you check for every feedName the metricName which matches it using filter. In the end, you can merge both with angular.merge.

var joinMetadataAndCustomers = function() {
  metadata.data.forEach(function(mtd) {
    customers.data.filter(function(customer) {
      return customer.metricName === mtd.feedName;
    }).forEach(function(customer) {
      $ctrl.metadataAndCustomers.push(angular.merge({}, mtd, customer));
    });
  });
}

Not sure if it's the best approach, but it works. Of course can be improved according to your needs. For example, if you only have one single match, the last forEach can be avoided.

Fiddle with an example: https://jsfiddle.net/virgilioafonsojr/tv1ujet0/

I hope it helps.