0
votes

Goal: I'm trying to update the "name" attribute of the crisis object in the html template.

Problem: The ngModel directive is not reading the initial crisis.name value into the html-input element and it is also not updating the name when the user edits the input field.

Problem Visualized:

Empty Input field that should be bound to crisis.name

Html template:

<h2>Crisis</h2>
<div *ngIf="crisis$ | async as crisis">
  <h3>"{{ crisis.name }}"</h3>
  <div>
    <label>Id: </label>{{ crisis.id }}</div>
  <div>
    <label>Name: </label>
    <input [(ngModel)]="crisis.name" >
  </div>
  <p>
    <button (click)="goToCrises(hero)">Back</button>
  </p>
</div>

Component:

export class CrisisDetailComponent implements OnInit {
  // The input decorator simply allows parent components to pass down a value to it
  // The parameter itself still acts as a normal attribute of the component
  public crisis$: Observable<Crisis>;

  constructor(
    private router: Router,
    private route: ActivatedRoute,
    private crisisService: CrisisService
  ) { }
  public ngOnInit(): void {

    console.log('detail initialized');
    this.crisis$ = this.route.paramMap.pipe(
      switchMap((params: ParamMap) => this.crisisService.getCrisis(params.get('id')))
    ); 
  }

  public goToCrises(crisis: Crisis): void {
    const crisisId = crisis ? crisis.id : null;
    this.router.navigate(['../', { id: crisisId, foo: 'foo' }], { relativeTo: this.route });
  }

}
1
You're initialising the ngModel inside changeName function , but you're not calling that function anywhere - Faizal Hussain
Hey @Faizal. The changeName() function was there only for testing purposes, the 2-way data binding in the html template should be entirely handled by the ngModel call but it is not working, thanks for the reply though! - Silas Grygier
Did you import FormsModule? Also, can you print crisis.name just to make sure it's not an empty string. - aeberhart
Hey @aeberhart, FormsModule is imported. When I print the crisis.name it returns the initial crisis name that was initially loaded in, meaning that the ngModel directive has not changed it's value :( - Silas Grygier
Strange... Can you try <input [value]="crisis.name" (keyup)="crisis.name=$event.target.value"> instead of [(ngModel)]="crisis.name" ? - aeberhart

1 Answers

-2
votes

You have to split the two-way binding to two one-way bindings:

<input [ngModel]="(crise | async)?.name" (ngModelChange)="loadValueChange($event)"> 

Now, in your component make a loadValueChange(newValue) method that will update the value on your observable