2

I have a GET method that returns the following JSON on route localhost:3000/documents

[{
"id": "5b48bffc644fca001419769c",
"names": [{
        "name": "bob"
    },
    {
        "name": "stan"
    }
],
"cities": [{
        "city": "London"
    },
    {
        "city": "Madrid"
    }
]
}]

I want to concatenate all the names and cities and display them inside HTML tags with Angular.

<p> id </p>
<p> concatenated names here </>
<p> concatenated cities here </>

Is it possible to access documents and concatenate the array values using ngFor?

I have the following component:

import {Component, OnInit} from '@angular/core';
import {DocumentService} from '../services/document.service';
import {Document} from './document.model';

@Component({
  selector: 'app-document',
  templateUrl: './document.component.html',
  styleUrls: ['./document.component.css']
})
export class DocumentComponent implements OnInit {
  documents: Document[];

  constructor(private documentService: DocumentService) {
  }

  ngOnInit() {
    this.getDocuments();
  }

  getDocuments(): void {
    this.documentService.getDocuments()
      .subscribe(documents => this.documents = documents);
  }
}

And the following service:

import {Injectable} from '@angular/core';
import {HttpClient, HttpHeaders} from '@angular/common/http';

import {Document} from '../document/document.model';

@Injectable({providedIn: 'root'})
export class DocumentService {

  private urlDocuments = 'localhost:3000/documents';

  constructor(private http: HttpClient) {
    }

  getDocuments() {
      return this.http.get<Document[]>(this.urlDocuments);
  }
}

My document model is:

export class Document {
  public _id: string;
  public names: [{ name: string }];
  public cities: [{ city: string }];

  constructor(_id: string, names: [{ name: string }], 
      cities: [{ city: string }]]) {
  this._id = _id;
  this.cities=cities;
  this.names= name;    
  }
}
3
  • Are objects inside names and cities, let's say { "name": "bob" } and { "city": "Madrid" } intended to be a Document ? Commented Jul 13, 2018 at 18:02
  • I mean how is the JSON related to the code below it? If possible edit the post and clarify that. Commented Jul 13, 2018 at 18:03
  • Document model is: id: String, names:[name: string], cities:[city:string] Commented Jul 13, 2018 at 18:10

3 Answers 3

3

I have the solution, but you need to modify your object.

You have to override toString method for cities and names in your model:

test= [{
    "id": "5b48bffc644fca001419769c",
    "names": [{
      "name": "bob",
      toString: function(){return this.name;}
    },
      {
        "name": "stan",
        toString: function(){return this.name;}
      }
    ],
    "cities": [{
      "city": "London",
      toString: function(){return this.city;}

    },
      {
        "city": "Madrid",
        toString: function(){return this.city;}

      }
    ]
  }];

HTML section will be look like:

<div *ngFor="let t of test">
  <p> {{t.id}}</p>
  <p> {{t.names.join(",")}}</p>
  <p> {{t.cities.join(",")}} </p>
</div>

Output:

5b48bffc644fca001419769c

bob,stan

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

4 Comments

I don´t want to touch the API, and I am a noobie with Angular. Is it possible to do on the Angular side?
Yes, As i wrote before, you add it with 2 ways. After response recieved or add to model. You could iterate and add this method for all elements
@RicardoMartin I'm just curious... how did you finally modified the API response in order to add the toString function?
@lealceldeiro convert to model where has toString method
2

Assume your documents data is getting no problem from server, then try this HTML code below:

 <div *ngFor="let d of documents">
  <p>Id: {{d.id}}</p>
  <p>Names: <span *ngFor="let dd of d.names">{{dd.name}},</span></p>
  <p>Cities: <span *ngFor="let dd of d.cities">{{dd.city}},</span></p>
</div>

1 Comment

This solution will be add comma to the last element. Output look likes Names: bob,stan, Cities: London,Madrid,
1

You just need to use an *ngFor in order to iterate over the documents and then two *ngFors for iterating over the names and the cities like this (StackBlitz Demo):

ts:

  documents = [{
    "id": "5b48bffc644fca001419769c",
    "names": [{"name": "bob"},{"name": "stan"}],
    "cities": [{"city": "London"},{"city": "Madrid"}]
  },{
    "id": "5b48bffc644fca001419769cde",
    "names": [{"name": "Jon"},{"name": "Doe"}],
    "cities": [{"city": "Barcelona"},{"city": "Saragoza"}]
  }
  ];

html:

<div *ngFor="let doc of documents; let last = last"> <!-- iterate over all documents, let last = last is optional -->
    <p>Id: {{doc.id}}</p>
     <!-- iterate over all names (n) for every document (doc) -->
    <p>Names: <span *ngFor="let n of doc.names; last as lastName">{{n.name}}{{lastName ? '': ','}} </span></p>
     <!-- iterate over all cities (c) for every document (doc) -->
    <p>Cities: <span *ngFor="let c of doc.cities; last as lastCity">{{c.city}}{{lastCity ? '': ','}} </span></p>
     <!-- optional , this will add a separator between documents-->
    <hr *ngIf="!last"/>
</div>

Output:

enter image description here

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.