What is the best way to display data in the view using Angular 5 by utilizing models, classes, or interfaces?

I am facing an issue while trying to display the data fetched from my backend. I have created a class to handle the data:

When I request the User by ID URI, the returned data looks like this:

https://i.sstatic.net/76BSY.jpg

Similarly, when I request all Users using another URI, the data is returned in the following format:

https://i.sstatic.net/5Aetm.jpg

I have implemented two functions in my service:

    getUserProfile(id): Promise<void | UserProfile> {
        let url = URL_SERVICIOS + '/users/' + id;
        let token2 = localStorage.getItem("TOKEN");
        let headers = new Headers();
        headers.append('Authorization', 'Bearer ' + token2);
        let options = new RequestOptions({headers: headers});

        return this.http.get(url, options)
          .toPromise()
          .then(response => response.json().result as UserProfile)
          .catch(this.handleError);
      }


  getUserProfileS(sort = '-createdAt'): Promise<void | UserProfile[]> {
    let url = URL_SERVICIOS + '/users/'
    return this.http.get(url)
      .toPromise()
      .then(response => response.json() as UserProfile[])
      .catch(this.handleError);
  }

In my component, I have the following code:

 usuario:UserProfile;

 this._ups.getUserProfile(id).then((user:UserProfile)=>{
     alert("USUARIO"+JSON.stringify(user));
     console.log(JSON.stringify(user));
     this.usuario=user;
     console.log(this.usuario.city);
   }).catch(err=>{
     console.log("ERROR"+err);
   })

The problem arises when I try to display the user's name in my view:

<h1>{{usuario.name}}</h1>

I receive an error message stating "Cannot read property 'name' of undefined", and I cannot pinpoint the error in my code.

Furthermore, I'm unsure whether I should be using interfaces or classes for this purpose.

The structure of my class 'UserProfile' is as follows:

 export class UserProfile {
  id: number;
  photoProfile?: any;
  id_facebook?: any;
  name: string;
  surname: string;
  email: string;
  password: string;
  latitude: number;
  longitude: number;
  country_code: string;
  telephone: string;
  city: string;
  birth: number;
  photo_profile?: any;
  gender: string;
  who_is?: any;
  roles?: any;

  constructor(values: Object = {}) {
    Object.assign(this, values);
  }
}

Answer №1

After your request, I have refactored your code to utilize RxJS Observables instead of Promises. Keep in mind that I haven't tested it yet, so if any errors are displayed, simply follow the instructions provided. Additionally, error handling is not included here as it is straightforward with Observables. It can serve as a beneficial exercise for you too. Here's how you can implement this using observables:

Create a service that will return a RxJS Observable rather than a promise:

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

import { UserProfile } from 'USER_PROFILE_PATH';


@Injectable()
export class UserService {
URL_SERVICES = YOUR_URL_HERE;


constructor(
  private http: HttpClient,
) { }


getUserProfile(id): Observable<UserProfile> {
    const url = `${URL_SERVICES}/users/${id}`;
    const token2 = localStorage.getItem("TOKEN");
    const headers = new HttpHeaders();
    headers.append('Authorization', `Bearer ${token2}`);
    const options = new RequestOptions({headers: headers});

    return this.http.get(url, options);
}

Your component that will receive the observable:

import { Component, OnInit } from '@angular/core';

import { UserProfile } from 'USER_PROFILE_PATH';
import { UserService } from 'USER_SERVICE_PATH';

@Component({
  selector: 'app-your',
  templateUrl: './your.component.html',
  styleUrls: ['./your.component.css']
})
export class YourComponent implements OnInit {

  user: UserProfile;

  id = SOME_ID_HERE;

  constructor(private userService: UserService) { }

  getUserProfile(): void {
    this.userService.getUserProfile()
        .subscribe(user => this.user = user);
  }

  ngOnInit() {
    this.getUserProfile(this.id);
  }

}

Answer №2

When utilizing the promise approach instead of observables, which is my preference,

In your service, make sure to return the promise itself:

getUserProfile(id): Promise<void | UserProfile> {
    let url = URL_SERVICIOS + '/users/' + id;
    let token2 = localStorage.getItem("TOKEN");
    let headers = new Headers();
    headers.append('Authorization', 'Bearer ' + token2);
    let options = new RequestOptions({headers: headers});

    return this.http.get(url, options).toPromise()
}

Then in the component, you can utilize then and access the user.result:

Instead of using this.usuario=user;, opt for this.usuario = user.result;

this._ups.getUserProfile(id).then((user:UserProfile)=>{
     alert("USUARIO"+JSON.stringify(user));
     console.log(JSON.stringify(user));
     this.usuario=user.result;
     console.log(this.usuario.city);
   }).catch(err=>{
     console.log("ERROR"+err);
   })

You can find additional documentation and examples here.

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

Determine the array with the highest value by comparing multidimensional arrays in JavaScript

I have a multidimensional array with names and corresponding integer values. I want to compare the integer values within each nested array to find and return the one with the highest value. var nums = [ ['alice', 'exam', 60], [ ...

Tips on transferring a file (such as PDF, DOC, etc) from a Client application built with React to a server built with Node.js and Express

Client-side To retrieve the PDF, I utilize an input file: <html> <body> <input type="file" id="file_attachments" name="files" onChange=updateAttachments() multiple> </input> <script> function updateAttachments() { let ...

Encountering an Unexpected Token error while using the getjson function

I need help parsing JSON data from an API feed, but I'm having trouble getting the JSON to parse correctly into an array. Here's a snippet of my JSON file. You can find the full file at the following location: JSON location: { "odata.metadata ...

Optimizing media queries with Angular: A comprehensive guide

I am currently using NgZone to handle media queries in my Angular project. I am curious if there is a more efficient way to achieve this. import { NgZone } from '@angular/core'; const SMALL_WIDTH_BREAKPOINT = 840; export class AppComponent im ...

Steps to create an if statement using jQuery

.data( "autocomplete" )._renderItem = function( ul, item ) { return $( "<li></li>" ) .data( "item.autocomplete", item ) if ( ( item.parent_term_id == "16" ) ) { .append( "<a>" + (item.child_term ? item.child ...

How should the directory be organized for the param with a prefix in Nuxt.js?

My route is set up as /en/rent-:productSlug How should I organize the directory for this route, considering that the parameter productSlug includes the prefix rent? ...

Harnessing the power of Vue.js within an Nw.js project, sans bundlers: Unveiled

I am currently developing a software application using NW.js and Vue.js. I have decided to build the application without reliance on compilers or bundlers. Although I have successfully installed the Vue.js library via npm, I am facing an issue where it i ...

Angular 4 - Seeking clarification on the usage of *ngComponentOutlet

When using *ngComponentOutlet, the following code snippets are employed to handle the displaying: Below is a snippet of functional code: this.displayComponent({ 'objects':[ {component: ToDisplayAComponent, expanded: fals ...

While working in Next.js, I utilized an `<Image />` tag with a link to an image, only to encounter an unexpected error

I've attempted it numerous times, but the error persists. I even went ahead and created the next.config.js file. module.exports = { images: { domains: ['link.papareact.com', ], }, }; Error: The src prop (https://links.pap ...

How to show a div for small screens only using Bootstrap 4 beta?

Previously, in Bootstrap alpha 6 I was able to achieve this by writing the following code for displaying a div's contents only for sm: <div class="hidden-md-up hidden-xs-down"> This content would only be visible for sm in Bootstrap 4 alpha 6 ...

Creating instances of a child class in Typescript using a static method in the parent class, passing arguments and accessing other static methods

Struggling with instantiating a child class from a static method in a base class. Looking to properly specify the return type instead of resorting to using any for all static methods. Tried a solution here, but it falls short when dealing with static metho ...

Performing a fetch() POST request in Express.js results in an empty body object being generated

Purpose: Implement a function in fetch() to send specified string data from the HTML document, for example "MY DATA" Here is the code snippet: HTML Code: <!DOCTYPE html> <html> <body> <script type="text/javascript"> function ...

Guide on showcasing an array in a table using DataTables in a single column

I find myself in a difficult situation because I am using DataTables for pagination and searching in an unconventional way. I have a table where I display vendor details such as names, emails, addresses, countries, and the materials they deal with. To fetc ...

Converting important information from elements in an Array into a string separated by commas

Which lodash method or function is best suited for extracting the ids from the array below and creating a comma-separated string out of them? var myArray = [ { tag: 'wunwun', id: 132 }, { tag: 'davos&apos ...

AngularJS enables the creation of multiselectable dropdown checkboxes

I am looking to create a dropdown list of checkboxes that allows for multiple selections. I have attempted to implement the code below, but I am facing an issue where the template refreshes each time a checkbox is clicked, preventing me from making multi ...

Potential causes for Chrome to send duplicate requests

In my nginx server logs, I have the following entries (IPs and paths altered for illustration purposes): 101.101.101.101 - - [15/Apr/2020:14:46:03 +0000] "GET /item/download-file/ready/5e971e290107e HTTP/2.0" 200 142940 "https://example.com/referer" "Mo ...

Dealing with textarea in Javascript

I am new to JavaScript and facing a challenge in creating a delimited string from a textarea input. The issue is that when the textarea is passed in, it includes newlines for each row. I aim to parse the entire textarea content into a string with a delimit ...

Is the Vue-portal enabled conditionally?

I am looking to include some additional information in the navbar (parent component) using Vue Portal. So, within a component, I can use the following code: <portal to="navbar"> <b-button>Some option</b-button> </portal&g ...

The error message "TypeError: Unable to access the 'getFullWidth' property of an undefined value when using TSLint and TypeScript" was

I have been using Dan Wahlin's tutorials and online examples to set up Gulp and Typescript, but I am facing an issue with the tslint() function. The problem occurs in my code as follows: node_modules\tslint\lib\language\walker&bso ...

Enhancing image search functionality through dynamic HTML updates

I need help figuring out how to update the link address for profile pictures on my NHL stats website. Currently, I am using a script to append the image to the body, but I don't know how to properly add the player ID ({{p1_ID}}) to the link and includ ...