Miguel Moura
Miguel Moura

Reputation: 39384

Map service response to Component Model to display on view

I have a Post API that returns the following:

{
  "data": [
    {
      "id": 1,
      "title": "Title 1",
      "content": "Lorem ipsum",
      "category": { id = 2, name = "A" }
      "created_at": "2018-10-20 10:14:23"
    },
    {
      "id": 2,
      "title": "Title 2",
      "content": "Lorem ipsum",
      "category": { id = 4, name = "P" }
      "created_at": "2018-12-20 12:17:41"
    }
  ]
}

I have a Post List component, to display the top posts, where I call the API, using a PostService, that returns the previous response:

export class PostListComponent implements OnInit {    

  posts: PostListModel[];

  constructor(private postService: PostService) { }    

  ngOnInit() {

    this.posts = this.postService.getTopPosts()
                     .subscribe(???);
  }    

}

The PostListModel is as follows:

export interface PostListModel {
  id: number;
  title: string;
  content: string;
  categoryName: string;
  hidden: boolean;
}

So on my component I need to map the API response to PostListModel[] where all properties with same name are just copied and categoryName and hidden are:

API Category.Name > PostListModel categoryName
PostListModel hidden = false (for all posts)

Hidden is a property that allows the user, on the view, to set a row, e.g. a Post, to hidden. So it has no relation to the API response.

Note: note sure if this is the best way to go ...

Upvotes: 0

Views: 92

Answers (3)

Gergő Kajtár
Gergő Kajtár

Reputation: 492

I would do like this:

The models:

 export class APIResponseItem {
              id: number
              title: string;
              content: string;
              category: { id: number, name: string }
              created_at: Date
    }


export class PostListModel {
  id: number;
  title: string;
  content: string;
  categoryName: string;
  hidden: boolean;

  constructor(data?: APIResponseItem) {
    if(data) {
      this.id = data.id;
      this.title = data.title;
      this.content = data.content;
      this.categoryName = data.category.name;
      this.hidden = false;
    }
  }
}

Service:

this.postService.getTopPosts().subscribe((response: APIResponseItem[]) => {
      this.posts = [];
      response.forEach(item => {
        this.posts.push(new PostListModel(item))
      });
    });

Upvotes: 1

User3250
User3250

Reputation: 3423

You can use spread operator for props whose name exactly matches in your component subscribe method like:

this.postService.getTopPosts()
.subscribe((s)=>{
  this.posts = s.data.map((item)=>{
    return {
     ...item,
     categoryName:item.category.name
    }
  }
});

Upvotes: 2

Sunil
Sunil

Reputation: 11243

You can map your data once you receive it from the API

export class PostListComponent implements OnInit {    

  posts: PostListModel[];

  constructor(private postService: PostService) { }    

  ngOnInit() {

    this.posts = this.postService.getTopPosts().map(post=>{id:post.id, title:post.title, content:post.content, categoryName : post.category['name'],  hidden : false}).subscribe(posts=> this.posts);
  }    

}

Note : you can do the same mapping in Service class itself.

Upvotes: 1

Related Questions