0

I'm binding an input tag's value to an ngmodel.

<input type="text" id="Fname" value="{{getProfile.firstname}}" placeholder="FirstName" #FirstName/>

Here is my typescript component

export class EditprofileComponent implements OnInit {

  getProfile: Profile;

  constructor(private profileService: ProfileService)

  ngOnInit() {
    this.profileService.getProfile().subscribe(data =>{
      this.getProfile = data;
      console.log(data);
    })
  }

When I use console.log(data). The console writes out an object of type Profile. So I'm getting the correct data.

I've done this same exact thing with the ngFor directive. But it's not working for a regular input value.

How do I bind the Profiles first name as the value for the input tag?

JD333
  • 501
  • 8
  • 22
  • 1
    You need to be careful, because `getProfile` will start off undefined. Use `{{getProfile?.firstname}}` instead which will take care of doing null checks for you – user184994 Nov 10 '18 at 23:58
  • Possible duplicate of [Angular2: Cannot read property 'name' of undefined](https://stackoverflow.com/questions/39755336/angular2-cannot-read-property-name-of-undefined) – HDJEMAI Nov 11 '18 at 00:33

3 Answers3

0

change the syntax to -

value="{{getProfile?.firstname}}"
Sunil Singh
  • 11,001
  • 2
  • 27
  • 48
Natan Farkash
  • 256
  • 3
  • 4
  • While this might answer the authors question, it lacks some explaining words and/or links to documentation. Raw code snippets are not very helpful without some phrases around them. You may also find [how to write a good answer](https://stackoverflow.com/help/how-to-answer) very helpful. Please edit your answer. – hellow Nov 12 '18 at 08:13
0

It's asynchronous, so you need to add ensure that the data is loaded in the template before the component renders. There are a few options to fix this:

Simple solution

Add the existential operator/safe navigation operator ? (to check if your variable exists):

getProfile?.firstname

Or

Wrap your input in an ng-container with *ngIf.

<ng-container *ngIf="getProfile">
// Add your input here
</ng-container>

Best/Better practice

Use a resolver to ensure the data is loaded before the component is rendered.

https://alligator.io/angular/route-resolvers/

jburtondev
  • 2,827
  • 1
  • 14
  • 20
  • 1
    What about the [safe-navigation operator](https://angular.io/guide/template-syntax#the-safe-navigation-operator----and-null-property-paths)? – user184994 Nov 11 '18 at 00:10
  • I know that firstname exists based off the console. This didn't work for me. – JD333 Nov 11 '18 at 00:29
  • 2
    @JD333 Yes, but that `console.log` is printed **after** the template is rendered, hence the error. The profile is being loaded asynchronously. – user184994 Nov 11 '18 at 00:39
  • @JD333 have you tried: `[value]="getProfile?.firstname"`? – jburtondev Nov 11 '18 at 00:43
  • @jburtondev I did, and thanks for that. But it's kind of irrelevant to the topic. – JD333 Nov 11 '18 at 00:52
  • @user184994 .. just when you think you understand observables you make a silly mistake and forget everything lol – JD333 Nov 11 '18 at 00:57
  • @JD333 Have you got it working now? I take it this solution fixed your issue? – user184994 Nov 11 '18 at 00:58
  • @JD333 OK cool. If an object was being returned (you haven't defined a return type for your function), then the string interpolation for attribute binding would not work. Hence why I asked. Hope you have resolved your issue. – jburtondev Nov 11 '18 at 01:04
  • No not really. I'm still having a problem. I've also rendered this information from a previous component. All I'm doing is subscribing to the current profile. And then displaying it. – JD333 Nov 11 '18 at 22:22
0

You can use the async pipe for observables (it will also unsubscribe when component is destroyed so you won't havo to do it manually) it will look like this:

getProfile: Observable<Profile>;

ngOnInit() {
  this.getProfile=this.profileService.getProfile();
}

html:

<input *ngIf="getProfile | async as profile" type="text" id="Fname" value="{{profile.firstname}}" placeholder="FirstName" #FirstName/>
Ofek Amram
  • 452
  • 2
  • 6