2

I am trying to merge two array of objects which the first array has a json file and the second the same but the second it holds the id of the first array of objects. I am trying to add the second array of objects for each to the right item of the first array of objects. As you can see the comments has an postId where it knows which post it belongs.

My json file it looks like this.

{
  "posts": [
    {
      "userId": 1,
      "id": 1,
      "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
      "body": "quia et suscipit suscipit recusandae consequuntur expedita et cum reprehenderit molestiae ut ut quas totam nostrum rerum est autem sunt rem eveniet architecto"
    },
    {
      "userId": 1,
      "id": 2,
      "title": "qui est esse",
      "body": "est rerum tempore vitae sequi sint nihil reprehenderit dolor beatae ea dolores neque fugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis qui aperiam non debitis possimus qui neque nisi nulla"
    },
    {
      "userId": 1,
      "id": 3,
      "title": "ea molestias quasi exercitationem repellat qui ipsa sit aut",
      "body": "et iusto sed quo iure voluptatem occaecati omnis eligendi aut ad voluptatem doloribus vel accusantium quis pariatur molestiae porro eius odio et labore et velit aut"
    },
    {
      "userId": 1,
      "id": 4,
      "title": "eum et est occaecati",
      "body": "ullam et saepe reiciendis voluptatem adipisci sit amet autem assumenda provident rerum culpa quis hic commodi nesciunt rem tenetur doloremque ipsam iure quis sunt voluptatem rerum illo velit"
    },
    {
      "userId": 1,
      "id": 5,
      "title": "nesciunt quas odio",
      "body": "repudiandae veniam quaerat sunt sed alias aut fugiat sit autem sed est voluptatem omnis possimus esse voluptatibus quis est aut tenetur dolor neque"
    },

and the same json but with another API to get data.

"comments": [
    {
      "postId": 1,
      "id": 1,
      "name": "id labore ex et quam laborum",
      "email": "[email protected]",
      "body": "laudantium enim quasi est quidem magnam voluptate ipsam eos tempora quo necessitatibus dolor quam autem quasi reiciendis et nam sapiente accusantium"
    },
    {
      "postId": 1,
      "id": 2,
      "name": "quo vero reiciendis velit similique earum",
      "email": "[email protected]",
      "body": "est natus enim nihil est dolore omnis voluptatem numquam et omnis occaecati quod ullam at voluptatem error expedita pariatur nihil sint nostrum voluptatem reiciendis et"
    },
    {
      "postId": 1,
      "id": 3,
      "name": "odio adipisci rerum aut animi",
      "email": "[email protected]",
      "body": "consectetur cumque impedit blanditiis non eveniet odio maxime blanditiis amet eius quis tempora quia autem rem a provident perspiciatis quia"
    },
    {
      "postId": 1,
      "id": 4,
      "name": "alias odio sit",
      "email": "[email protected]",
      "body": "impedit nostrum id quia aut est fuga est inventore vel eligendi explicabo quis consectetur aut occaecati repellat id natus quo est ut blanditiis quia ut vel ut maiores ea"
    },
    {
      "postId": 1,
      "id": 5,
      "name": "vero eaque aliquid doloribus et culpa",
      "email": "[email protected]",
      "body": "harum non quasi et ratione tempore iure ex voluptates in ratione harum architecto fugit inventore cupiditate voluptates magni quo et"
    },
    {
      "postId": 2,
      "id": 6,
      "name": "et fugit eligendi deleniti quidem qui sint nihil autem",
      "email": "[email protected]",
      "body": "doloribus at sed quis culpa deserunt consectetur qui praesentium accusamus fugiat dicta voluptatem rerum ut voluptate autem voluptatem repellendus aspernatur dolorem in"
    },
    {
      "postId": 2,
      "id": 7,
      "name": "repellat consequatur praesentium vel minus molestias voluptatum",
      "email": "[email protected]",
      "body": "maiores sed dolores similique labore et inventore et quasi temporibus esse sunt id et eos voluptatem aliquam aliquid ratione corporis molestiae mollitia quia et magnam dolor"
    },

I have created a model and service to define data and to get data.

export class Post {
  userId: number;
  id: number;
  title: string;
  body: string;
}

import {Injectable} from '@angular/core';
import {HttpClient} from '@angular/common/http';
import {Observable} from 'rxjs';


@Injectable({
  providedIn: 'root'
})

export class PostService {
  private baseUrl = 'http://localhost:3000/posts';

  constructor(private http: HttpClient) { }

  getPost(id: number): Observable<any> {
    return this.http.get(`${this.baseUrl}/${id}`);
  }

  getPostsList(): Observable<any> {
    return this.http.get(`${this.baseUrl}`);
  }

  deletePost(id: number): Observable<any> {
    return this.http.delete(`${this.baseUrl}/${id}`);
  }

And this is the component

export class PostsListComponent implements OnInit {
  public posts: Observable<Post[]>;

  constructor(private postsService: PostService) { }

  ngOnInit() {
  this.comments$ = this.commentsService.getCommentsList();
  this.posts = this.postsService.getPostsList();

  this.groupedComments$ = this.comments$.pipe(
  map(comments => lodash.groupBy(comments, 'postId'),
  ));
 }
 }

HTML code

<tr class="row" *ngFor="let post of posts | async">
        <td class="col">{{post.title}}</td>
        <td class="col-6">{{post.body}}</td>
        <td class="col"><button (click)="deletePost(post.id)" class="btn btn-danger">Delete</button>
          <button (click)="postDetails(post.id)" class="btn btn-info" style="margin-left: 10px">Details</button>
        </td>
      </tr>
2
  • Can you tell what is your expected output array? Commented Nov 10, 2019 at 18:32
  • @AshishPatel I am expecting that I can show the posts and comments in one array and then which comments belongs to which post for example. Commented Nov 10, 2019 at 18:35

1 Answer 1

3

I recommend to group the comments by postId, for example with lodash

this.groupedComments$ = this.comments$.pipe(
  map(comments => lodash.groupBy(comments, 'postId')),
);

Then you can simply access this object in template

<tr class="row" *ngFor="let post of posts | async">
        <td class="col">{{post.title}}</td>
        <td class="col-6">{{post.body}}</td>
        <td class="col">
           <div *ngFor="let comment of groupedComments[post.id]">{{comment}}</div>
        </td>
        <td class="col"><button (click)="deletePost(post.id)" class="btn btn-danger">Delete</button>
          <button (click)="postDetails(post.id)" class="btn btn-info" style="margin-left: 10px">Details</button>
        </td>
      </tr>

(async-pipe groupedComments$ anywhere before)


Edited:

interface Comment {
  postId: number;
  id: number;
  name: string;
  email: string;
  body: string;
}

interface CommentGroup {
  [key: number]: Comment[];
}

comments$: Observable<Comments[]>;
groupedComments$: Observable<CommentGroup>;
Sign up to request clarification or add additional context in comments.

9 Comments

as what you define the this.groupedComments$ and the this.comments$
comment$ is your observable of comments just like posts. groupedComments$ is the pipe-mapped result
Added, is that what you wanted?
I am facing with an error. ERROR TypeError: Cannot read property '1' of undefined I don't know why I have added everything as you added in the code.
maybe your posts-observable is completed before the comments-observable. Please make sure to only show the data when both observables completed
|

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.