1

I am trying to retrieve data for multiple IDs like this:

(Heavily simplified, but I hope I can make my point clear)

Controller:

var idList = [39,40,41];
$.each(idList, function(key, value){
  var dataObject = {
    type: "test",
    id: value
  };
  var getData = DataFactory.get(dataObject);
  getData.then(function(result){
    console.log(result);
  }
});

Factory:

app.factory("DataFactory", ['$http', '$rootScope',
  function($http, $rootScope){
    url = 'http://url/api';
    var obj = {};
    obj.get = function(object){
      return $http({
        method: 'GET',
        params: object,
        url: url
      })
      .then(function(results){
        return results.data;
      });
    };
    return obj;
  }
]);

Backend:

<?php
  $id = $_GET['id'];
  $type = $_GET['type'];

  echo json_encode(array("id": $id, "type": type, "value": "value matching id ".$id));
?>

If the idList is 1 integer, the data returned matches the id eg:

{id: 39, type: "test", value: "value matching id 39"}

However, when applying multiple values in the idList, the returned data is not applied to the correct id:

{id: 39: type: "test", value: "value matching id 41"}
{id: 40: type: "test", value: "value matching id 39"}
{id: 41: type: "test", value: "value matching id 40"}

I expected that if I'd send back the same ID, the value matching that ID would be correct. This is not the case. Is there any way I can properly bind the ID to the correct matching value?

Edit: Looking at the network tab in chrome the following happens:

For 1 id

url: api?id=39&type=test
result(preview): data: [id: 39, type: test, value: 'value matching id 39']

For 3 id's

url: api?id=39&type=test (same for 40 and 41)
result(preview): data: [id: 39, type: test, value: 'value matching id 40']

It almost looks like php is not handeling the requests properly. Opening the api url (http://url/api?id=39&type=test) always gives me the expected result. Calling the api multiple times from javascript gives me mixed up results.

SanderW
  • 31
  • 3

2 Answers2

0

Its looking right, maybe is the PHP is not identifying the "GET" action.

Did you try to put a console.log in the factory to see if is taking the right url? (and its good to see the network).

And you can also do in the "bad way" (just to test), putting the url hard-coded like this:

url: url + "?id=" + object.id + "&type=" + object.type
Fabio Picheli
  • 939
  • 11
  • 27
  • I tried your suggestion, but the results are the same. I did a console.log(object) and console.log(results) (for the .get and the results) The object has all the correct parameters, but the result gives me the incorrect value for that specific ID. The php script returns a value based on that ID and the ID itself. So i cannot figure out why the result from the http.get is wrong. – SanderW Feb 15 '16 at 11:19
  • and you get same result? – Fabio Picheli Feb 15 '16 at 11:20
  • You can check the request on the browser network tool (I prefer the chrome ou firefox http://stackoverflow.com/questions/4423061/view-http-headers-in-google-chrome) – Fabio Picheli Feb 15 '16 at 11:26
  • The GET URL is correct (from your network tool suggestion), individually the combination ID+type works and returns the expected JSON. I have also tried this with the Advanced REST client extention in chrome. Thats why I'm suspecting it has something to do with the async nature of these requests. – SanderW Feb 15 '16 at 11:29
  • Strange. Opening the api url from the network tools window gives me the correct value matching the ID. However when checking the 'preview' tab, the data is not correct. – SanderW Feb 15 '16 at 11:50
0

In case you are having this problem in java when using spring configuration with jersey, the problem may be caused by the singleton nature of the resource when marked with @component. When a new request arrives, the same bean is used with the old injected values for query, header params, and other business objects. This means that it will fetch data using old values.

One way to fix it is to use prototype scope on the resource class to get a new instance with fresh injection each time there is a request: @Scope("prototype") or to modify the get method signature so that all the values it needs such as parameters are injected at the method instead of into the object.

The second option is better because the instance will be reused and only parameters will be changing for each method call.

Instead of this

@QueryParam("searchTerm")
private String searchTerm;

@GET
private Product findProduct() {
    productDao.find(searchTerm);
}

Do this

@GET
private Product getProduct(@QueryParam("searchTerm") String searchTerm) {
    productDao.find(searchTerm);
}