20

I understand using observable I can execute a method when the request is completed, but how can i wait till a http get is completed and return the response using in ng2 http?

getAllUser(): Array<UserDTO> {
    this.value = new Array<UserDTO>();
    this.http.get("MY_URL")
                    .map(res => res.json())
                    .subscribe(
                        data => this.value = data,
                        err => console.log(err),
                        () => console.log("Completed")
    );

    return this.value;
} 

the "value" will is null when its returned because get is async..

2
  • 1
    You can either use $q service or execute your function in ajax success callback Commented Oct 23, 2015 at 5:10
  • 1
    @Vineet Angular 2 does not use $q Commented Sep 27, 2017 at 19:32

8 Answers 8

3

your service class: /project/app/services/sampleservice.ts

    @Injectable()
    export class SampleService {

      constructor(private http: Http) {
      }

      private createAuthorizationHeader() {
         return new Headers({'Authorization': 'Basic ZXBossffDFC++=='});
      }


      getAll(): Observable<any[]> {
        const url='';
        const active = 'status/active';
        const header = { headers: this.createAuthorizationHeader() };
        return this.http.get(url + active, header)
          .map(
            res => {
              return res.json();
            });
      }

    }

your component: /project/app/components/samplecomponent.ts

export class SampleComponent implements OnInit  {


  constructor(private sampleservice: SampleService) {
  }

  ngOnInit() {
   this.dataset();
  }

  dataset(){
    this.sampleservice.getAll().subscribe(
      (res) => {
        // map Your response with model class
        // do Stuff Here or create method 
        this.create(res);
      },
      (err) => { }
    );
  }
  create(data){
   // do Your Stuff Here
  }

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

1 Comment

when ever the response changes observable automatically call your method and updates with new elements.
3

enter image description hereBy looking at the angular source (https://github.com/angular/angular/blob/master/packages/http/src/backends/xhr_backend.ts#L46), it is apparent that the async attribute of the XMLHttpRequest is not getting used. The third parameter of XMLHttpRequest needs to be set to "false" for synchronous requests.

1 Comment

Sync requests are no more supported on most browsers . For a better UI experience...
0

Please find code for your problem Below is component and service file.And Code is Working fine for synchornize

import { Component, OnInit } from '@angular/core';
import { LoginserviceService } from '../loginservice.service';

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {
  model:any={};
  constructor(private service : LoginserviceService) { 
}

ngOnInit() {

}
save() {
   this.service.callService(this.model.userName,this.model.passWord).
   subscribe(
      success => {
        if(success) {
            console.log("login Successfully done----------------------------    -");
            this.model.success = "Login Successfully done";
     }},
    error => console.log("login did not work!")
  );
 }

}

Below is service file..

import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import { UserData } from './UserData';
import 'rxjs/add/operator/map'
import 'rxjs/add/operator/toPromise'
import {Observable} from 'rxjs/Rx'

@Injectable()
   export class LoginserviceService {
   userData = new UserData('','');   
   constructor(private http:Http) { }

    callService(username:string,passwrod:string):Observable<boolean> {
     var flag : boolean;      
     return (this.http.get('http://localhost:4200/data.json').
       map(response => response.json())).
        map(data => {
          this.userData = data;
          return this.loginAuthentication(username,passwrod);
        });
      }

  loginAuthentication(username:string,passwrod:string):boolean{
     if(username==this.userData.username && passwrod==this.userData.password){
        console.log("Authentication successfully")
        return true;
   }else{
     return false;
   }


  }
}

Comments

0

Another solution would be to implement a priority queue of sort.

From what I understand http requests do not get executed until you add subscribers. Therefore, you can do something like this:

Observable<Response> observable = http.get("/api/path", new RequestOptions({}));

requestPriorityQueue.add(HttpPriorityQueue.PRIORITY_HIGHEST, observable,
                 successResponse => { /* Handle code */ }, 
                 errorResponse => { /* Handle error */ });

This assumes that requestPriorityQueue is a service injected into your component. The priority queue would store entries in an array in the following format:

Array<{
    observable: Observable<Response>, 
    successCallback: Function, 
    errorCallback: Function
}>

You would have to decide how the elements are added to your array. Finally, the following will happen in the background:

// HttpPriorityQueue#processQueue() called at a set interval to automatically process queue entries

The processQueue method would do something like this:

protected processQueue() {
    if (this.queueIsBusy()) {
        return;
    }

    let entry: {} = getNextEntry();
    let observable: Observable<Response> = entry.observable;

    this.setQueueToBusy(); // Sets queue to busy and triggers an internal request timeout counter.
    observable.subscribe()
        .map(response => {
            this.setQueueToReady();
            entry.successCallback(response);
        })
        .catch(error => {
            this.setQueueToReady();
            entry.errorCallback(error);
        });
}

If you are able to add new dependencies you could try using the following NPM package: async-priority-queue

Comments

0

I looked and I couldn't find any way to make an HTTP call sync instead of async.

So the only way around this: wrap your call in a while loop with a flag. Don't let the code continue until that flag has "continue" value.

Pseudo code as follows:

let letsContinue = false;

//Call your Async Function
this.myAsyncFunc().subscribe(data => {
   letsContinue = true;
}; 

while (!letsContinue) {
   console.log('... log flooding.. while we wait..a setimeout might be better');
}

Comments

-3

as you see, first callback waiting for a data from request and there you can go on with your logic (or use the third one)

example:

.. subscribe( data => { 
              this.value = data; 
              doSomeOperation;
              }, 
              error => console.log(error), 
              () => {console.log("Completed");
                      or do operations here..;
                    }
});

1 Comment

Can you enter an other subscribe request in the "do operations here..." place?
-4

How about to use $.ajax(of jQuery) or XMLHttpRequest.

It can use as asynchornize.

4 Comments

jQuery should not be used with Angular
I dont think so.
Why do you think so? Some programer use jQuery by preference in Angular.
Angular already has Http in 2 and HttpClient in 4.3 to do async http requests. Also, read here about why it's bad to use jQuery with Angular: stackoverflow.com/questions/41834089/…
-10

You should not try to make http calls behave synchronously. Never a good idea.

Coming to your getAllUser implementation it should return an observable from the function and the calling code should subscribe instead of you creating a subscription inside the method itself.

Something like

getAllUser(): Observable<UserDTO> {
        return this.http.get("MY_URL")
                        .map(res => res.json());
} 

In you calling code, you should subscribe and do whatever you want.

6 Comments

This response offers an alternative implementation to the questions and I appreciate the response. However, this does not answer the question. Is there no way to make a synchronous http request? I am looking for an answer to the same question and I am OK with blocking the browser (in fact I want it to) until I get the response.
This answer only suggests not to use sync xhr, it never explains the reason in the question's use case nor even answers the question in any way but only provides an answer to another question.
By looking at the angular source, it seems the async attribute of the XMLHttpRequest is not getting used.
@inki Making a "sync" request in a browser would freeze the whole browser. That's a horrible user experience.
@inki See this Google post from Jan 2012 about no longer allowing Synchronous XHRs developers.google.com/web/updates/2012/01/…
|

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.