2

I have been looking around how could I make my code wait for the http request before move on, the reason that I need it is because I'm using the response to fill some variables in the html.

So,

Question 1: Do I really need to create a Service to make a http request and return a Promise/Observable?

Question 2: This is my code, couldn't I just do something here to make the code wait for the response?

let link = 'http://working url';
      let headers = new Headers({
          'Content-Type': 'application/x-www-form-urlencoded',
          'Accept': '*/*'
      });

      let options = new RequestOptions({headers: headers});

      this.http
          .post(link, this.loginString, options)
          .map(res => res.json())
          .subscribe(
              data => {
                  let response = JSON.parse(data);
                  if(response.Successfull){
                      if(response.ReturnObject.length>0){
                          this.orders = this.orderJson(response.ReturnObject);
                          this.ordersWithoutGroup = response.ReturnObject;
                          this.empty = false;

                      }else{
                          this.orders= [];
                          this.empty= true;
                      }
                  }

          }, err => {
              this.showAlertError();
          }, () => {
              this.loadingPopup.dismiss()

          });
}

Thank you in advance for the help.

EDIT 1: HTML:

<ion-content class="stable-bg" scroll="true">
 <div class="item-input-inset">
     <label class="item-input-wrapper">
         <i class="icon ion-ios-search placeholder-icon"></i>
         <input type="text" placeholder="Search Orders" ng-model="search">
     </label>
 </div>
 <ion-list *ngIf="orders !== null" ng-repeat="(date, group) in orders">
     <ion-item class="item-divider">{{ date }}</ion-item>
     <ion-item class="item-icon-left item-icon-right" ng-repeat="order in group" (click)="goToDetail(order.ID)">
         <div ng-show="order.DocumentNumber.indexOf(search) >-1 || !search ">
             <i class="icon ion-card"></i>
             <div>Nº {{ order.DocumentNumber }}
                 <span class="gray pull-right">{{ order.time }}</span>
             </div>
             <i class="icon ion-ios-arrow-right"></i>
         </div>
     </ion-item>
 </ion-list>
 <div ng-show="empty">
     <div class="card">
         <div class="item item-text-wrap ion-information-circled" (click)="check()">At the moment there isn't any order to
approve.</div>
     </div>
  </div> 
</ion-content>

More code about the .ts:

import { Component , OnInit, Injectable} from '@angular/core';
import { NavController, AlertController, LoadingController } from 'ionic-angular';
import { Http, Headers, RequestOptions} from '@angular/http';
import * as moment from 'moment';


@Injectable()
@Component({
selector: 'page-orders',
templateUrl: 'orders.html'
})
export class OrdersPage implements OnInit{

    orders: any;
    loginString: any;
    empty: boolean;
    ordersWithoutGroup: any;
    loadingPopup: any;;

constructor(public navCtrl: NavController,private alertController: AlertController,  private http: Http, private loadingCtrl: LoadingController) {
 this.loadingPopup = this.loadingCtrl.create({
  content: 'Loading orders...'
});

// Show the popup
this.loadingPopup.present();
  this.orders= {}
  this.loginString = localStorage.getItem("Auth");

}

ngOnInit() {
        this.getOrders();
    }

EDIT 2: My console.log about the orders: console.log(this.orders);

1 Answer 1

4

Question 1: Do I really need to create a Service to make a http request and return a Promise/Observable?

This really depends on your implementation. Doing http.post() from the same component should not make any difference, technically. Although, some advantages to have a common service is -

  1. Modular code - As in service's purpose is to give you data. A particular component's purpose is to handle operations on that component only.

  2. Reuse - If a service is to be used from different components with more or less same behaviour, the same service can be reused and manipulated using parameters.

This is my code, couldn't I just do something here to make the code wait for the response?

The whole purpose of .subscribe() is for that. You can move all your code which is waiting for the response in this.

As for the html variables as you need, I have 2 solutions for you.

  1. Use ngIf in components UI in tags. Here, you can check for conditions like if data variable is still null or not null. In case it is not null show it. E.g. <p *ngIf="_data !== null">Show data : {{_data}}</p>. This does not need to wait for your data. Whenever the data loads, the UI will get updated.

  2. Load all the data in the previous page only. And once it is loaded push the page with navParams in .subscribe() and then render. (This was just for fast modification in your code.)

Sign up to request clarification or add additional context in comments.

5 Comments

For some reason it don't work for me if I use the ngIf it sill not auto loading the UI...
Edit the question with both .html and .ts code. There should not be any reason for this to not work.
Assuming your getOrders() contain the http.post() code that you have written, can you check what is getting printed at console using console.log("Data :",this.orders); after this.orders = this.orderJson(response.ReturnObject); line. Also, please put a console.log() at various points in your .post() code to check the flow and if the values are present as you want. At a guess, I also think let response = JSON.parse(data); is not needed, since you already used .map(res => res.json). Try doing let response = data; and check once again. Answer all these for me.
I had already done it, my (click)="check()" was already showing the log for orders... about the JSON.parse(data) if I don't do it, the I just get a huge string since the server response is in a string format, not in JSON... Thank you for your help so far.
@JoãoSilva You need to DEBUG this correctly. I have given you the tools to do it. Use console.log(), (click)=function() very efficiently. Even try printing the values without the for loop directly like <p>{{orders[0].data}}</p> and see what happens. Also, what does the server return? If you have used .map(res => res.json), then it already converts your raw data to json. Unless server is returning invalid data.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.