2
votes

Hello folks I will keep my question very simpler by showing code

  1. I am using Json placeholder site for the fake rest Api
  2. I have a user class Object
  3. I want to convert returned Observable to the custom class object array.
    import { Injectable } from '@angular/core';
    import { HttpClient } from '@angular/common/http';
    import { Observable } from 'rxjs';
    import { Users } from './users.model';
    
        @Injectable({
          providedIn: 'root'
        })
        export class UsersService {
        
          private url = "https://jsonplaceholder.typicode.com";
        
          constructor(private http:HttpClient) {
            console.log(this.getUsers());
           }
        
        
          getUsers():Observable<Users[]>{
            return this.http.get<Users[]>(`${this.url}/posts`);
        }
        
        }

The above is my service

    export class Users {
        email:          string;
        id:             number;
        name:           string;
        phone:          string;
        username:       string;
        
    }

above is my class I haven't included all properties

In my typescript file I have code like.

constructor(private _usersService:UsersService) {
    
  }

  ngOnInit(): void {
   
    this._usersService.getUsers().subscribe(data=>this.users=data);

    console.log(this.users);
  }

Now the things I want is

  1. how to convert returned observable in my custom class object?
  2. I don't have all the fields so how is it possible to map only those fields which I want?

Hope my question is clear..!!

2
please make it a little more clear for me. so your API returns an observable with an array of objects and you want to make changes on those objects and return the array that is modified?Mj Jameel
yes exactly you can hit jsonplaceholder.typicode.com/users and it returns the array of json objects the thing I need is 1) I need to convert into my custom object 2)If I dont need all the properties I can be able to map only the some property for example it has geo property but as you can see I dont have it so I can have objects of my own custom class is it possible?kushal Baldev
yes its possible ill write a function for that one minMj Jameel

2 Answers

3
votes

so this answer takes advantage of map() which is imported from rxjs.

before subscribing we are going to pipe a map() function into the observable stream and then map() each element from that array into a new object that fits our User interface

then we subscribe and the data we get then will be an array that fits our User interface

ngOnInit(): void {
   
    this._usersService.getUsers()
    .pipe(map(data => {
      return data.map(item => {
        const user: User = {
          name: item.name,
          email: item.email,
        }
        return user
      })
    }))
    .subscribe(data=>this.users=data);

    console.log(this.users);
  }
1
votes

You can do like below, in the User class have a constructor and return User while mapping

import { Component, VERSION, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { map } from 'rxjs/operators';

export class User {
    email: string;
    id: number;
    name: string;
    phone: string;
    username: string;

    constructor( user: User ) {
      Object.assign( this, user );
    }
}

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})

export class AppComponent implements OnInit  {
  name = 'Angular ' + VERSION.major;

  constructor(private http: HttpClient){}

  ngOnInit() {
    this.http.get<User[]>("https://jsonplaceholder.typicode.com/users")
    .pipe(
      map( data => {
        return data.map( ( user ) => {
          return new User( {
            email: user['email'],
            id: user['id'],
            name: user['name'],
            phone: user['phone'],
            username: user['username'],
          } );
        } );
      } ),
    )
    .subscribe( (users : User[]) => console.log(users) );
  }
}

Working stackblitz