0
votes

I have a list of users like in the image: List of Users

When I click on one user, I want to show a new page with the details of that user. Therefore I made a new component called "details" and put this HTML code into the details.component.html file:

<div *ngIf="user$">
  <h1>{{ user$.name }}</h1>

  <ul>
    <li><strong>Username:</strong> {{ user$.username }}</li>
    <li><strong>Email:</strong> {{ user$.email }}</li>
    <li><strong>Phone:</strong> {{ user$.phone }}</li>
  </ul>
</div>

and in my details.component.ts i put this code:

import { Component, OnInit } from '@angular/core';
import { DataService } from '../data.service';
import { ActivatedRoute } from "@angular/router";

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

user$: Object;

constructor(private route: ActivatedRoute, private data: DataService) { 
  this.route.params.subscribe( params => this.user$ = params.id );
  console.log(this.user$)
}

ngOnInit() {
  this.data.getUser(this.user$).subscribe(
    data => {
      this.user$ = data;
      console.log(this.user$)
      }
    );
  );
}

}

So what I'm doing here is: I take the userId as a parameter from the URL (this part works fine, I checked it with the console.log(this.user$) and it gets logged.) Then I load the User with this Id from my Data Service (this part works too, again checked with the log) And then I call the user$ up from the HTML, it first compiles successfully, but then after some seconds this error appears:

ERROR in src/app/details/details.component.html:3:10 - error TS2339: Property 'name' does not exist     
on type 'Object'.

   <h1>{{ user$.name }}</h1>

the same error comes for Property 'username', 'phone' and email'.

I think the problem is that the observable hasn't loaded yet at the moment the html tries to access it, but that's why I put the , so that this code only gets executed when it has loaded... Please help

p.s. I came up with this code following this tutorial: https://coursetro.com/posts/code/154/Angular-6-Tutorial---Learn-Angular-6-in-this-Crash-Course But I even copied the code snippets directly from the tutorial and it still doesnt work.

p.p.s according to the tutorial I would need to import Observable in the details.component.ts file, but my program shows me that the import is never used. So I removed the import and weirdly I'm still able to subscribe to the Observable? Maybe there's the problem?

Here's the console log:

console log

1
Although your approach doesn't look clean to me, typing user$ with a correct type should fix your issue. to start with you can verify it with typing by any: ``user$: any - Ashish Ranjan
please share code of this.data.getUser() - satanTime
first, you should not be using using single variable for everything. I am agree with @AshishRanjan, try using 'any' instead of 'Object' - YogendraR

1 Answers

1
votes

I see multiple issues here.

  1. Change the type definition from Object to any.
  2. Conventionally, dollar sign at the end of a variable is used to denote an observable. Here it doesn't denote an observable.
  3. Edit the code so that the asynchronous calls are streamlined. I am using RxJS switchMap to project the observable from getUser() on receiving the parameters from route. Try the following
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from "@angular/router";

import { switchMap } from 'rxjs/operators';

import { DataService } from '../data.service';

@Component({
  selector: 'app-details',
  templateUrl: './details.component.html',
  styleUrls: ['./details.component.scss']
})
export class DetailsComponent implements OnInit {
  user: any;

  constructor(private route: ActivatedRoute, private data: DataService) { }

  ngOnInit() {
    this.route.params.pipe(switchMap(params => this.data.getUser(params['id'])))
      .subscribe(
        data => {
          this.user = data;
          console.log(this.user);
        }
      );
  }
}
  1. Use safe navigation operator ?. in the template to make sure user is defined before accessing it's properties.
<div *ngIf="user">
  <h1>{{ user?.name }}</h1>

  <ul>
    <li><strong>Username:</strong> {{ user?.username }}</li>
    <li><strong>Email:</strong> {{ user?.email }}</li>
    <li><strong>Phone:</strong> {{ user?.phone }}</li>
  </ul>
</div>