简体   繁体   中英

Convert JSON to Typescript Interface including Date method

On Angular 7 I have the following Post Model:

export interface PostModel {
  id: number;
  created: Date;
  published: boolean;
  title: string; 
}

And I have the following Angular service method to get posts:

public getPosts(): Observable<PostModel[]> {

  return this.httpClient.get<PostModel[]>(url).pipe(

    map((post: PostModel)) => {

      return {
        id: post.id, 
        created: new Date(post.created),
        published: post.published,
        title: post.title
      };

    })

  };

I am converting the API response to PostModel manually ...

This is because created type is Date and Angular does not converts it automatically.

I would like to reuse the mapping code in different parts of my code:

map((post: PostModel)) => return mapPostFromJson(post));

I could convert PostModel to class and mapPostFromJson as its method.

But I would prefer PostModel to keep being an interface.

How can I do this?

Update

My problem is how to create the mapPostFromJson method. I tried:

mapPostFromJson(data: any) : PostModel {

  return map((post: PostModel) => {

    return { 
      id: post.id, 
      created: new Date(post.created),
      published: post.published,
      title: post.title
    };

  });

}

This function does not compile ...

I am not sure how to use map outside pipe ...

I am not sure I understand your question correctly, but, would that mapping function work?

mapPostFromJson(data: any): PostModel {
    return { 
        id: data.id, 
        created: new Date(data.created),
        published: data.published,
        title: data.title
    };
}

Otherwise, using functional principles, you could make a more generic solution by defining general functions that you can reuse to build your mappers:

// This function takes a structure of functions, and applies
// them to some data, returning a structure of the results
const mapper = functions => json => Object.entries(json)
    .map(([k, val]) => ({ [k]: (functions[k] || (x => x))(val) }))
    .reduce((acc, o) => Object.assign(acc, o), { });

You can then easily create a mapper and call it on your JSON:

// create a mapper that passes all properties
// but transforms 'created' to a date
const mapPostFromJson = mapper({
    created: x => new Date(x)
});

const post = mapPostFromJson(jsonPost);

Using this mapper, all JSON properties will pass through, but the created field will be transformed to a date.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM