Ways to dynamically link a JSON response object to an entity?

In my ng2 implementation, I have a user.service.ts file that calls a REST service and returns JSON data. The code snippet below shows how the getUser function retrieves the user information:

getUser(id: number): Promise<User> {
    return this.http.get('http://localhost:4000/users/1')
        .toPromise()
        .then(response => response.json())
}

The JSON object returned from the service has the following structure:

{
   "Id":"1"
   "FirstName":"John"
   "LastName":"Smith"
}

I want to convert this JSON object into an instance of my ng2 User entity, which is defined as follows:

export class User 
{
    Id: number;
    FirstName: string;
    LastName: string;
}

I am looking for a generic way to map the userResponse to the User entity without writing explicit mapping code each time. Ideally, I would like to automate this process using reflection or similar dynamic techniques. Is there a recommended approach to achieve this in ng2?

Answer №1

It appears from the feedback that you aim to avoid implementing a constructor in your class. A straightforward approach to achieve this is by utilizing Object.assign():

fetchUser(id: number): Promise<User> {
  return this.http.get('http://api.example.com/users/1')
    .map(response => Object.assign(new User(), response.json()))
    .toPromise()
}

Your retrieved data will now be an instance of User.

Try it out here: (monitor the console for output)

Answer №2

To extract the keys of your json object's properties, iterate through them and assign each one to your object's properties using their respective names.

.then(json => {
    Object.keys(json).forEach(key => user[key] = json[key]);
});

If you prefer a reusable function, you can create one like this:

export class User {
    // declare properties here
    mapResponse(response) {
        Object.keys(response).forEach(key => this[key] = response[key]);
    }
}

getUser(id: number): Promise<User> {
    var user = new User();

    this.http.get('http://localhost:4000/users/1')
        .toPromise()
        .then(response => response.json())
        .then(newUser.mapResponse);

    return user;
}

This is my first attempt at writing TypeScript, so I hope this helps you get started in the right direction.

Answer №3

Creating a constructor within your class declaration allows you to properly initialize the class:

export class User 
{
    Id: number;
    FirstName: string;
    LastName: string;
    constructor(obj: any) {
      this.Id = +obj['Id'];
      this.FirstName = obj['FirstName'];
      this.LastName = obj['LastName'];      
    }
}

To see it in action, check out this plunker.

If you need to dynamically set and reset values, you can create a method like this:

let user = setUser(this.userResponse); // <-- Assuming this.userResponse is the returned object

setUser(res) {
  return {
    Id: +res['Id'],
    FirstName: res['FirstName'],
    LastName: res['LastName']
  };
}

Answer №4

For my project, I've opted to utilize Observables instead of Promises in my code. Here is an example:

getUserDetails(id: number): Observable<User> {
    return this.http.get('http://myapi/users/' + id)
             .map(response => response.json());
}

In situations where a Promise is required:

getUserDetails(id: number): Promise<User> {
    return this.http.get('http://myapi/users/' + id)
        .map(response => response.json())
        .toPromise();
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

How do I trigger a click on a menu item that is lazy loaded when testing Angular with Cypress?

I attempted to execute a small cypress test by trying to navigate to a lazy loaded page, but unfortunately it did not work as expected. The URL path I aimed for was: 'angular-page/angular-page-content1' My approach: describe('1st. test&apos ...

The div element fails to display even after invoking a JavaScript function to make it visible

As a newcomer to JavaScript & jQuery, please bear with me as I ask a very basic question: I have created the following div that I want to display when a specific JavaScript function is called: <div id='faix' class="bg4 w460 h430 tac poa ...

Having issues with NGXS subscription not functioning properly when selecting a variable

Currently, I am working with Angular 11 and NGXS. One issue I am facing involves a subscription for a variable in the state. Here is the problematic subscription: @Select(state => state.alert.alerts) alerts$: Observable<any[]> ngOnInit(): void { t ...

Typescript - using optional type predicates

I'm looking to create a custom type predicate function that can accurately determine if a number is real and tighten the type as well: function isRealNumber(input: number | undefined | null): input is number { return input !== undefined && ...

Utilizing Jquery to Pass an Optional Function to Another Function

I am currently working on a function that utilizes AJAX to submit data and then displays a dialog indicating whether the process was successful or not. Everything seems to be functioning smoothly, but I now want to add the capability of passing an addition ...

How does Chrome have the capability to access the gist json file? Isn't that typically not allowed?

Fetching a JSON file from Github Gist can sometimes be straightforward, but in certain situations, I have faced difficulties due to CORS restrictions. This has led me to resort to using JSONP instead. Can you shed some light on why this is the case? ...

The TypeScript compiler is searching in an external directory for the node_modules folder

My angular 2 project is located in the directory /c/users/batcave/first_project. In that same directory, I have various files such as index.html, systemjs.config.js etc., and a node_modules folder that only contains @types and typescript. This means my @a ...

Determine the full location information with the help of Google Maps SDK without the need

My current challenge involves dealing with a list of unformatted and incorrectly written addresses. I am seeking a way to iterate through these flawed strings and generate more organized and accurate addresses using one of the many Google Maps SDKs availa ...

Setting up jsdoc on a computer with slow internet access can be a bit tricky, but with

Recently, I have been working on some JavaScript code and utilized the sublime jsdoc plugin for commenting. Now, my goal is to generate documentation from these comments. The challenge lies in the fact that I am developing this JavaScript on a machine loca ...

Encountering an error while utilizing ngForm in an HTML form

I have developed a custom component called "login", where I created an HTML form named "login.component.html". To convert this form into an Angular form, I added the code "" in login.component.html and imported import {NgForm} from '@angular/forms&apo ...

Discover the flawless way to transmit client geolocation to a server. Encounter an intriguing hurdle: Unable to access undefined properties (specifically 'loc') while reading

I encountered an error that says "TypeError: Cannot read properties of undefined (reading 'loc')". This error was triggered when I attempted to pass the user's location to a server through a POST request. In my HTML file, I have included th ...

The Capacitor Community Electron Platform, which combines IONIC, Angular, and Electron, encountered a TypeError: [ERR_INVALID_ARG_TYPE]. This error message indicates that the "path" argument must be in the

I have been attempting to follow the guidelines provided on to integrate the Capacitor Community Electron into a brand new Ionic Angular Test App. Everything is going smoothly until I reach the step where I need to add the platform as per the instructions ...

Understanding special characters within a URL

Here is a URL example: postgres://someuser:pas#%w#@rd-some-db.cgosdsd8op.us-east-1.rds.amazonaws.com:5432 This URL is being parsed using the following code snippet: const url = require('url'); const { hostname: host, port, auth, path } = url.par ...

Having trouble displaying the API response data on the screen in Next.js

I am currently experiencing an issue with my OCR API that is supposed to return text from a given image. The data is being received on the client side and can be seen in the console. However, for some reason, the element is not updating with the data. Bel ...

Ext.js Ext.grid.Panel with advanced filtering capabilities

I encountered an issue with the following code snippet... Ext.define("Requestor.view.main.RequestGrid", { extend: 'Ext.grid.Panel', // Our base class. A grid panel. ... extensive code ... columns: [ ... additional code ... { ...

Execute a JavaScript function repeatedly, with a specified delay incorporated into it

I am currently working on a JavaScript function that cycles through background images within a div. The function works well, but it stops once all the images have been displayed. How can I make it start over again after going through all the images? $(do ...

The asyncData function in Nuxt is throwing a surprise setTimeout (nuxt/no-timing-in-fetch-data)

Having trouble running a code on my pages/posts/index.vue page where I keep getting an error message 'Unexpected setTimeout in asyncData'. Can anyone provide assistance in understanding this error and suggest if any additional plugins are needed? ...

The term 'Buffer' is not recognized in the context of react-native

Having trouble using buffer in my react-native app (developed with the expo tool). I have a hex value representing a geography Point like this for example -> 0101000020E61000003868AF3E1E0A494046B3B27DC8F73640 and I'm attempting to decode it into l ...

When using string as a primitive type in Vue 3, what distinguishes the usage of PropType in props from not using it?

The documentation explains how Vue does runtime validation on props with defined types. To enable TypeScript to recognize these types, constructors are cast with PropType. The code example in the documentation uses success: { type: String }, whereas it c ...

"Error: Discord Js encounters an issue trying to access the titles property of an

Having trouble with a random number generator in my discord bot. Whenever someone enters +nhr, it may work or display an error message in the console: TypeError: Cannot read property 'titles' of undefined and Unhandled promise rejection. Thi ...