1

For example, I have a JSON data as below from JSONPlaceholder website https://jsonplaceholder.typicode.com/users.

[
  {
    "id": 1,
    "name": "Leanne Graham",
    "username": "Bret",
    "email": "[email protected]",
    "address": {
      "street": "Kulas Light",
      "suite": "Apt. 556",
      "city": "Gwenborough",
      "zipcode": "92998-3874",
      "geo": {
        "lat": "-37.3159",
        "lng": "81.1496"
      }
    },
    "phone": "1-770-736-8031 x56442",
    "website": "hildegard.org",
    "company": {
      "name": "Romaguera-Crona",
      "catchPhrase": "Multi-layered client-server neural-net",
      "bs": "harness real-time e-markets"
    }
  },
  {
    "id": 2,
    "name": "Ervin Howell",
    "username": "Antonette",
    "email": "[email protected]",
    "address": {
      "street": "Victor Plains",
      "suite": "Suite 879",
      "city": "Wisokyburgh",
      "zipcode": "90566-7771",
      "geo": {
        "lat": "-43.9509",
        "lng": "-34.4618"
      }
    },
    "phone": "010-692-6593 x09125",
    "website": "anastasia.net",
    "company": {
      "name": "Deckow-Crist",
      "catchPhrase": "Proactive didactic contingency",
      "bs": "synergize scalable supply-chains"
    }
  }]

From this array of objects, I want array of objects with username and name as below:

[
{"name": "Leanne Graham",
    "username": "Bret"},
{    "name": "Ervin Howell",
    "username": "Antonette"
}
]

I am using Httpclient to access JSON data. My code in app.component.ts is as below:

interface user {
      username : String,
    name : String
}

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnInit {
  users : Observable<user>
  constructor(private _http : HttpClient){}
  name = 'Angular ' + VERSION.major;
  ngOnInit() {
   this.users = this._http.get('https://jsonplaceholder.typicode.com/users')

I am accessing array of users with async pipe in app.component.Html as below:

<div *ngFor = "let user of users | async" >
 {{user.Username}}
 {{user.name}}
</div>

I have tried building type interface for entire json object and there by filtering with map operator but it is too much for a large amount of JSON data. Any other solution will be really helpful Thanks in advance.

1
  • 1
    map operator is the easiest way. Why not use it as it is? Commented Sep 16, 2020 at 4:45

2 Answers 2

2

The map operator is the way to go. You are asking for a solution that is better than O(n) complexity, but you will always have to go through the entire array of objects one way or another, meaning that a linear complexity is the minimum you'll get. You can always use a regular for loop to iterate the data, and then push to a new array, but that will give you some overhead time as well.

A good rule of thumb is that when you want to modify the data in an array, map is the way to go.

this.users = this._http.get('https://jsonplaceholder.typicode.com/users').pipe(
    map(users => users.map(user => ({ name: user.name, username: user.username })))
);
Sign up to request clarification or add additional context in comments.

3 Comments

He's looking for a different solution, read his question again.
@Daniel, Your solution worked perfectly without creating interface for JSON data (although we need to modify HTTP GET request to this._http.get<user[]>). But, I just want to know how a nested map is different from single one. ex : In above code, you have used map operator twice. How it is making the difference while using it once is not working properly? Any reference docs regarding the same will be really helpful.
There is a big difference though, we're using both the RXJS map operator, and the Array.map function, they are not one and the same. Since the HttpClient will return an observable with an Array as it's type, it will emit the whole array as the entity, not the actual contents. They are similar in the way that they return a new Array / Observable with each element that's been transformed.
0

Here is a sample code to modify existing array of objects using map operator.

Considering user as your interface i.e.

interface user {
  username : String,
  name : String
}

let modifiedArray: Array<user> = this.users.map(user => {
  return <user>{
    username: item.username,
    name: item.name
  }
})

Try to check/log modifiedArray & let me know if it prints what you need. Please share your feedback.

2 Comments

Actually we are dealing here with HTTP request which will return data in Observable type. we need to use map operator from `RXJS'. Solution provided by @Daniel works perfectly. Please have a look into it. Thanks for your response
Yes, that is correct answer if you need to modify the actual response coming from the HTTP request. But my answer can be helpful in case, where you need to keep original response aside & modify it for as per the requirement for other purpose. So then you will have original response & your modified array/object. Happy to see your problem has resolved. Thanks for your feedback.

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.