Return data from an HTTP request at Angular

Asked

Viewed 678 times

0

I need to make a simple request that will return only one JSON. I am trying to do this using the following function:

.ts:

getModel(modelId: number) {
  let modelName: any = "none";
  this.carService.getModel(modelId).subscribe(
    data => modelName = data['name']);
  return modelName;
}

service:

getModel(id: number) {
    return this.http.get<any[]>(`${this.getModelByIdUrl + id}`);
}

But he returns undefined. Can find it right, but does not assign the variable modelName. How can I do that? I just need the function to return what it received from the request.

  • I think you missed the whole context of what you need, because I didn’t understand why you use the service within a function. Where you call the function getModel(modelId: number)?? Apparently this function is redundant.

2 answers

2

What happens is that http.get is a call asynchronous, that is, it is not guaranteed that it will return the results immediately, and the return may even execute before the get break up. http.get returns a Observable, whose method subscribe serves to indicate what to do when something is returned. So in your code:

this.carService.getModel(modelId).subscribe(
  data => modelName = data['name']);

return modelName;

The function that is within the subscribe (the code data => modelName = data['name'], which uses the syntax of Arrow Function) is a callback: she doesn’t perform immediately. You’re just saying: when the http.get return something, execute it.

Only the HTTP call may take time, and the return can be executed before the callback. That is, you may end up returning the modelName before it is set.


But it was not clear why you need to return this information. Why not use it directly within the callback? Ex:

this.carService.getModel(modelId).subscribe(
  data => {
    // use o data['name'] diretamente aqui dentro
  }
);

Or, if you only need name, you can use the operations pipe and map, to turn the return into another Observable:

import { map } from 'rxjs/operators';

getModel(modelId: number): Observable<string> {
  return this.carService.getModel(modelId).pipe(
    map(data => data['name'])
  );
}

Thus, getModel now returns a Observable<string>, that is, containing only the value of data['name'] (I’m assuming that data['name'] is a string; if not, change the return type of the Observable). The return must remain one Observable, for the call that gives rise to everything (http.get) is asynchronous, so if we try to return directly data['name'], we fell into the same problem as the original code.

Then you use getModel where necessary, remembering that now the return is the name (and no longer the object data):

this.getModel(1).subscribe(name => {
  // usar o name do jeito que quiser
});
  • Well, I did what you suggested. But then I need to take the amount and use it. Then I read that you need to use the subscribe, and fall into the same problem as before. Just to put you in context, I’m accessing an api that returns a json. But for example, the model is an id. and I need to find the model name using id. then throw all the dice in a table, cute. But I always hit the same problem...

  • 1

    @As the return of http.get is asynchronous, there is no way to use it synchronously (there is no way to only return the value as you want to do). If you need to use the data returned by get, the only way guaranteed is to do everything you need inside the subscribe, there’s no way out of it. You can even call a subscribe within another, i.e., call the API, catch the result in a subscribe, and within that subscribe can make another HTTP call to fetch the ID and call the ID subscribe (within which you throw the dice on the table), etc.

-1

Well, take for example that you are making a request waiting for a type object Car:

  getModel(id: number): Observable<Car> {
    return this.http.get<Car>(`${this.getModelByIdUrl + id}`);
  }

you need to specify in the call http.get that you expect an object that is assigned to the model Car.
Just as it is necessary to signal that the function returns a Observable of the kind <Car>.

  • So doing this didn’t change much for me. even because the service function was already working... I think the problem is in the function of . ts, where I do the assignment. I have already checked and the data gets there. The problem is that it does not persist in the variable model... (but thank you)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.