Search code examples
angulartypescriptrxjsangular2-http

Angular 4 combine data from multiple HTTP requests


I'm using angular 4 and I try to get data from 2 endpoints but I have a problem understanding rxjs.

with this code I can only get list of students and users only.

 getStudent() {
    return this.http.get(this.url + this.student_url, this.getHeaders()).map(res => res.json());
  }

getUsers() {
    return this.http.get(this.url + this.users_url, this.getHeaders()).map(res => res.json());
  }

Let's say this is data : Student

[{"ID" : 1 , "SchoolCode": "A150", "UserID": 1 }, 
{"ID" : 5 , "SchoolCode": "A140" , "UserID": 3}, 
{"ID" : 9 , "SchoolCode": "C140" , "UserID": 4}]

User

[{"ID" : 1  ,"Name": "Rick" , "FamilyName" , "Grimes" },
{"ID" : 4 ,"Name": "Carle" , "FamilyName" , "Grimes" }]

I want to get first all students then compare UserID if it's the same as user then I combine both objects into one until I get an array like this :

{"ID" : 1 , "SchoolCode": "A150","Name": "Rick" , "FamilyName" , "Grimes" }

I think I should use flatmap but I did try write code but it dosen't work for me and I didn't find an example with such logic.

Could you please help me.


Solution

  • You can use the switchMap operator (alias of flatMap) in the following code :

    // Observables mocking the data returned by http.get()
    const studentObs = Rx.Observable.from([
      {"ID" : 1 , "SchoolCode": "A150", "UserID": 1 }, 
      {"ID" : 5 , "SchoolCode": "A140" , "UserID": 4}, 
      {"ID" : 9 , "SchoolCode": "C140" , "UserID": 3}
    ]);
    const userObs = Rx.Observable.from([
      {"ID" : 1, "Name": "Rick" , "FamilyName": "Grimes" },
      {"ID" : 3, "Name": "Tom" , "FamilyName": "Cruise" },
      {"ID" : 4, "Name": "Amy" , "FamilyName": "Poehler" }
    ]);
    // Return an observable emitting only the given user.
    function getUser(userID) {
      return userObs.filter(user => user.ID === userID);
    }
    
    studentObs
      .switchMap(student => {
         return getUser(student.UserID).map(user => {
           // Merge the student and the user.
           return Object.assign(student, {user: user});
         })
      })
      .subscribe(val => console.log(val));
    

    Check out this JSBin: http://jsbin.com/batuzaq/edit?js,console