7

I am working on learning Angular 2 and Typescript. I am building a simple web application that grabs data from a WEB API and displays it in a list. Then once the user clicks an item in the list, they are taken to a details page.

I have a service that I created to make the API call that does the following:

   GetData() { 
         let data = this.http.get('http://server.name/api/GetData')
                  .map((res) => res.json());
         return data; 
   }

Then in a component, I subscribe to the data like this:

      this.myService.GetData()
      .subscribe((myService) => this.items = myService);

When the http.get returns, I would like to do some processing on the JSON objects before I return from the GetData() method. For example, add a new property called ID. Essentially something like the pseudo code below:

 for each(item in data) { 
     item.ID = newID(); //method for creating IDs 
 }
  1. Is this something that can be done?
  2. If yes, is it something that SHOULD be done, or is there a better way to accomplish what I am trying to do?

Thanks

2
  • This is not angularjs. There's already one map, what does stop you from adding an another one? The operator exists exactly for that. Commented Apr 20, 2017 at 1:40
  • Sorry, that was the tag suggested by Stack Overflow. Commented Apr 20, 2017 at 2:28

2 Answers 2

10

You can do the processing in your GetData's code, within the map:

// For RxJS v5 
    this.http
      .get('http://server.name/api/GetData')
      .map(result => {
         const items = <any[]>result.json(); // could be SomeItem[] instead of any[]
         items.forEach(item => item.ID = ...);
         return items;
      });

// For RxJS v6 
    this.http
     .get('http://server.name/api/GetData')
     .pipe(map(result => {
        const items = <any[]>result.json(); // could be SomeItem[] instead of any[]
        items.forEach(item => item.ID = ...);
        return items;
      }));

Then when you receive the object in your subscribe, the items should have the IDs assigned.

Here's the reference to the RxJs Observable's documentation: http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-map

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

Comments

2

the idea is to :

  • get the result
  • map the result to get the json only
  • as your json is an array, produce an Observable for each data, then change its id and sent the data back
  • gather them back in an array

the mergeMap (replaced flatMap in rxjs 5.5+) operator is used because an Observable operator always sends back an Observable, but since we create an Observable inside the result itself, it produces an Observable>, mergeMap removes an Observable layer. Hope this helps

GetData():Observable<WhateverWithIDInside[]> { 
  let data = this.http.get('http://server.name/api/GetData')
    .map(res => res.json())
    .mergeMap(dataArr =>
      Observable.from(dataArr)
        .map(data => {
          data.ID = newID();
          return data;
        })
        .toArray()
   );
}

1 Comment

I prefer this version because you don't need to subscribe to your observable so you could use the async pipe in Angular2

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.