6

I need to make an api call that returns me a response of id's and values associated with it. The promise then resolves and returns a true or false if the id queried was found or not found.

How can i achieve this? New to using promises. As is promises seem confusing

here is the end point on consuming the API, UserService returns an array of id's and salaries. I need to check if the id exists and the salary matches to the query and then the promise needs to resolve to true or false.

here is the object of id's and incomes

      [{
            "id": 1,
            "name": "Primary",
            "sal": [{
                    "id": "1",
                    "sal": "10"
                }, {
                    "id": "2",
                    "sal": "20"
                }]
            },{
            "id": 2,
            "name": "Secondary",
            "sal": [{
                    "id": "1",
                    "sal": "100"
                }, {
                    "id": "2",
                    "sal": "200"
                }
            ]
        }];


  UserService.hasUserValue(id, income).then(function(qualifiesforlowIncome){
     var isLowIncome = qualifiesforlowIncome
   }

qualifiesforlowIncome is a boolean that returns a true or false. I am using angular so in this case should i do a $q.defer and return a defer.promise ?

A little unclear on this

looneytunes
  • 741
  • 4
  • 16
  • 35
  • 1
    [Just `return` from the `then` callback](http://stackoverflow.com/a/22562045/1048572) the value that you need, and you've got your promise! – Bergi May 24 '17 at 19:43

3 Answers3

5

Sure, all you need to do is add a then case which determines if any of the objects match the query then return true or false from it. That value will get carried into the next then case.

In this example, I'm using the some method to see if any of the objects in the array match the condition.

Promise.resolve([
    {
      id: 1
    },
    {
      id: 2
    },
    {
      id: 3
    }
  ])
  .then(results => 
    results.some(r => r.id === 2)
  )
  .then(foundResult => console.log(foundResult));

Or rewritten in ES5:

Promise.resolve([
    {
      id: 1
    },
    {
      id: 2
    },
    {
      id: 3
    }
  ])
  .then(function(results) { 
    return results.some(r => r.id === 2);
  })
  .then(function(foundResult) {
    console.log(foundResult);
  });

This works exactly the same even if you return a Promise which later resolves.

Promise.resolve([
    {
      id: 1
    },
    {
      id: 2
    },
    {
      id: 3
    }
  ])
  .then(results => 
    // Return a promise, delay sending back the result
    new Promise((resolve, reject) => {
      setTimeout(() =>
        resolve(results.some(r => r.id === 2)),
        500
      );
    })
  )
  .then(foundResult => console.log(foundResult));
Mike Cluck
  • 31,869
  • 13
  • 80
  • 91
  • yes, I got the consuming part . But how would i return a promise that later resolves to true or false. do i need to use $q.defer and return a defer.promise ? – looneytunes May 24 '17 at 19:14
  • That's exactly what you need to do, take a look above at my example. – IAmKale May 24 '17 at 19:19
  • @looneytunes Do the exact same thing. Just return the Promise inside of your `then` case which resolves to `true` or `false`. The next `then` in the chain will get `true` or `false` as soon as the previous promise resolves. I've edited my answer to include this. – Mike Cluck May 24 '17 at 19:30
0

How do you make your api calls? Let's assume you use fetch.

const UserService = {
    getUsersWithIncome(income) {
        return fetch("your.api/users?income="+income).then(resp => resp.json());
    }
    hasUserValue(id, income) {
        return UserService.getUsersWithIncome(income).then(users => { 
            return users.some(u => u.id == id);
        });
    }
};

But by the way, the logic seems to be reversed here. So you have an endpoint that lists low income users and then look for a specific ID? Why dont you haven a rest endpoint that tells directly if a user with a given id has low income?

Tamas Hegedus
  • 28,755
  • 12
  • 63
  • 97
0

Edit: Don't do this! See Bergi's comment below for the reason why.

You'll want to use $q to return a deferred promise from hasUserValue(), make your API request within that method, and then resolve the promise after the API request finishes and you have a chance to crunch the numbers:

hasUserValue(id, income) {
  var dfd = $q.defer();

  SomeService.getSalaries().then(function(resp) {
    // Do some logic here with the response
    var qualifiesforlowIncome = someFuncThatDeterminesEligibility(resp);
    // This is the value that will be returned for `qualifiesforlowIncome` in your then() callback
    dfd.resolve(qualifiesforlowIncome);
  });

  return dfd.promise;
}

This is basically pseudo-code, the important bit is creating a deferred promise with AngularJS's $q and then returning the promise from the function as dfd.promise. The dfd object will have resolve() and reject() methods that can be used to pass back custom values in then() or catch() callbacks that you register when you call the method.

IAmKale
  • 3,146
  • 1
  • 25
  • 46
  • 1
    Avoid the [deferred antipattern](http://stackoverflow.com/q/23803743/1048572?What-is-the-promise-construction-antipattern-and-how-to-avoid-it)! – Bergi May 24 '17 at 19:42
  • Well I'll be damned, thanks for the link. It seems I need to study up more on Promises! – IAmKale May 24 '17 at 19:48