youssef elhayani
youssef elhayani

Reputation: 745

Problem when receiving data in Angular from the BackEnd part

I hope you are well, I encountered a small problem when I wanted to develop an Angular application , what I wanted exactly is to bring back a list of element "Menu" of my backend part to use it in my application.

The problem is that when i use the get method to bring back the data, this data is brought back to the end of the execution, i noticed this detail when i wanted to log the objects that i bring from the backEnd in console.

enter image description here

As you can see,when I log the MenuItem object in the constructor or in the Onint () method I get an empty object but when I log this object in the service class I get the menuTtem object, so I understand that the OnInit and Construtor are executing first and following the method http get in second.

My question is this: is there a way to recover the data without falling into this problem ?

here is my constructor in menu.component:

constructor(public appSettings: AppSettings, public menuService: MenuService) {
  this.settings = this.appSettings.settings;
  this.menuItems = this.menuService.getVerticalMenuItems();
  console.warn('this.menuItems in the construtor', this.menuItems)

}

and the getMenuItems () method of my Menu.service service

public getMenuItems(): Menu[] {
  this.http.get<Menu[]>(this.url + 'all').subscribe(
      data => { this.menudata = data
        console.warn('this.menudata in Service', this.menudata)
    }
  )
  return this.menudata ;

}

If there is any suggestion, do not hesitate.

Thank You !

Upvotes: 0

Views: 506

Answers (4)

Yuri
Yuri

Reputation: 4498

Well, to me it seems the code works as it should. You just need to understand the asynchronous nature of JS. You can't block the main JS thread with inherently slow network communication (a HTTP request-response roundtrip might take 200ms).

In this case the get function returns an Observable on which you can subscribe to new events. And that's it. In this case the event is a HTTP response. When HTTP response arrives it will assign the data to this.menudata and log the service message.

So, you subscribe to the Observable immediately but the subscription itself gets processed when a HTTP response arrives. It can't wait for the response and then continue. It would kill app's responsiveness.

// For more info about the concept, use relevant part of the official Angular guide.

Upvotes: 1

Seloka
Seloka

Reputation: 405

try this: subscribe to your API call in your ngOnInit() and not your services component

 ngOnInit() {
      this.settings = this.appSettings.settings;
      this.menuService.getMenuItems().subscribe(
      (data: any) => {  
        console.warn('this.menuItems in Service', data )
    }
  );

  } 

in your service component, do this. Do not forget to return the service call


 public getMenuItems() {
 return this.http.get<Menu[]>(this.url + 'all')
}

Upvotes: 0

Harout
Harout

Reputation: 76

You have to subscribe to Observable inside the component so that the data that is coming from the backend are reachable inside of the component.

notice that when you call getMenuItems() method of the Menu.service it returns the data that is assigned to menudata property in that particular time which is null in case of first call of the method.

that is happening because the observable is getting the over time "there is a delay" or in other words it is async operation

 public getMenuItems(): Observable<Menu[]> {
  return this.http.get<Menu[]>(this.url + 'all');
  }

and inside of you component

ngOnInit () {
this.menuService.getVerticalMenuItems().subscribe((data) => {
   this.data = data;
});

}

Upvotes: 0

Ganesh
Ganesh

Reputation: 6016

call your methods in ngOnInit() not in the constructor. When the getVerticalMenuItems() method is called, the thread is not waiting for the response so the parameter returning undefined. That's why you are getting undefined there.

do some changes like below,

  ngOnInit() {
      this.settings = this.appSettings.settings;
      this.menuService.getVerticalMenuItems();
      console.warn('this.menuItems in the construtor', this.menuItems)
  } 



 public getMenuItems() {
  this.http.get<Menu[]>(this.url + 'all').subscribe(
      (data: any) => { 
        this.menuItems = data
        console.warn('this.menuItems in Service', this.menuItems )
    }
  )
}

It's a better practice to subscribe your Observable response in Component.

Upvotes: 0

Related Questions