return a promise that resolves to a boolean true or false if a value is found
Asked Answered
D

3

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

Dowson answered 24/5, 2017 at 19:6 Comment(1)
Just return from the then callback the value that you need, and you've got your promise!Ufo
H
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));
Hobie answered 24/5, 2017 at 19:11 Comment(3)
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 ?Dowson
That's exactly what you need to do, take a look above at my example.Weiweibel
@Dowson 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.Hobie
W
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?

Warpath answered 24/5, 2017 at 19:16 Comment(0)
W
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.

Weiweibel answered 24/5, 2017 at 19:17 Comment(2)
Avoid the deferred antipattern!Ufo
Well I'll be damned, thanks for the link. It seems I need to study up more on Promises!Weiweibel

© 2022 - 2024 — McMap. All rights reserved.