0

I am using ionic 4. I get the result from the API then get the result show like this

[
 {"name":John,"age":20},
 {"name":Peter,"age":35},
 {"name":Alex,"age":15}
]

But I want to get the name only to check whether have same name with my condition or not. But I cannot straight a way get the result from the API, I need to hard code to do comparison. Here is my code:

 this.http.get(SERVER_URL).subscribe((res) => {
      const data = [
        { name: John, age: 21 },
        { name: Thomas, age: 25 },
    ];

      const ppl= data.find(people=> people.name === 'alex');
      console.log(ppl);
  });

So, My first question is How to get the name from the API directly, not like now I hard code the result from API. My Second Question is when I do comparison I want to show the result 'already exist' or 'can use this name'. Because if I write my code like this I will get the error Type 'void' is not assignable to type 'boolean':

const ppl= data.find((people)=> {
 if(people.name === 'alex') {
   this.text = 'already exist'
  } else {
  this.text = 'can use this name'
  }});
  console.log(ppl);

Anyone can help me? Thank you very much

qing
  • 785
  • 1
  • 10
  • 24
  • What data are you sending to the API? The name that the user is trying to get? Why aren't you using the response `res`? Where are you defining the variable `people`? What does it refer to? – Raul Sauco Jul 28 '19 at 00:28
  • Thank you for you reply, I do not send data to API. I want to get data from API. I defining the variable people is I want to try the code. Can delete one. – qing Jul 28 '19 at 03:25
  • What are you requesting from the API? Are you getting all the usernames that exist, like `api.example.com/names` , or are you sending the username entered by the user to filter? Like `api.example.com/names?search=alex`. If you are requesting **all** the usernames, besides increasing traffic, you are going to have to deal with paginating the results. – Raul Sauco Jul 28 '19 at 04:07
  • api.example.com only, then will output all result, like the image I show – qing Jul 28 '19 at 05:45
  • The image you showed of the server response shows an array, but your comment in my answer says that the server response is an object, please edit that and confirm which one is correct. – Raul Sauco Jul 28 '19 at 07:00
  • I already copy my response and edit at question. I check the type of res is show object – qing Jul 28 '19 at 09:23
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/197112/discussion-between-raul-sauco-and-qing). – Raul Sauco Jul 28 '19 at 09:53

1 Answers1

0

Instead of defining data, use the contents of the response; res will have the exact same contents that you are declaring in data.

this.http.get(SERVER_URL).subscribe(res => {

  // If successful, res is an array with user data like the following
  // [
  //   {name: "John", age: 21},
  //   {name: "Thomas", age: 25},
  //   ...
  // ]

  if (res.find(user => user.name === 'alex')) {
    console.log ('Username has been taken');
  } else {
    console.log('Username is available');
  }

});

Taken from the MDN docs on Array.prototype.find():

The find() method returns the value of the first element in the array that satisfies the provided testing function. Otherwise undefined is returned.

In that case

res.find(user => user.name === 'alex')

will return a user object if any of the usernames match alex, or undefined if none of the user.name attributes match alex.

undefined evaluates to false and a user object evaluates to true in the conditional.

Keep in mind that you are comparing strings with ===, so, for example, Alex will not match alex, if you want to look into other ways to compare strings, have a look at this question.

You also might want to handle errors, how you handle them is up to you, and it will depend on the response, but you can access the error inside your subscribe like this:

this.http.get(SERVER_URL).subscribe(res => {

  if (res.find(user => user.name === 'alex')) {
    console.log ('Username has been taken');
  } else {
    console.log('Username is available');
  }

}, error => {

  console.log(error);

}, () => {
  // There is also a 'complete' handler that triggers in both cases
});

Edit. API returns Object not array

If your API returns an Object instead of an array like in your question, you can still iterate over the properties

this.http.get(SERVER_URL).subscribe(res => {

  // If successful, res is an array with user data like the following
  // {
  //   key1: {name: "John", age: 21},
  //   key2: {name: "Thomas", age: 25},
  //   ...
  // }

  let match = false;

  Object.keys(res).forEach(key => {

    if (res[key].name === 'alex') {
      match = true;
    }

  });

  if (match) {
    console.log ('Username has been taken');
  } else {
    console.log('Username is available');
  }

});

Instead of Object.keys() you could use Object.values() to get an array with user objects, then use find() as before, but that seems less efficient, something like this:

if (Object.values(res).find(user => user.name === 'alex')) {
    console.log ('Username has been taken');
  } else {
    console.log('Username is available');
}
Raul Sauco
  • 2,645
  • 3
  • 19
  • 22
  • thank you for your reply. I get the error 'Property 'find' does not exist on type 'Object'. – qing Jul 28 '19 at 05:44
  • Then the API is not returning what you said, could you confirm what the API response is and make it clear in your question? Please, add the response as text and not as an image. – Raul Sauco Jul 28 '19 at 06:53