I'm using a for loop to display different sections of my blog for editing purposes.
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Route, ParamMap } from '@angular/router';
import { HttpClient } from '@angular/common/http';
import { Content } from '../model/Content';
@Component({
selector: 'app-edit-story',
templateUrl: './edit-story.component.html',
styleUrls: ['./edit-story.component.css']
})
export class EditStoryComponent implements OnInit {
story: any;
storyName: any;
isMe: boolean= false;
constructor(private route: ActivatedRoute, private httpClient: HttpClient) { }
ngOnInit(): void {
if (localStorage.getItem('userId')=='62e348924d52fa7420bb96bc') {
this.isMe = true;
}
this.storyName = this.route.snapshot.paramMap.get('storyName');
var url = 'http://localhost:3002/api/stories/' + this.storyName;
this.httpClient.get(url).subscribe(data => {
this.story = data;
console.log(this.story);
})
}
editStory() {
}
addContent() {
var newContent = new Content("", "", "");
this.story.contents.push(newContent);
}
}
<div *ngIf="isMe">
<form #editStoryForm = "ngForm" (ngSubmit)="editStory()" class="addStory">
<label for="title">Title</label>
<input name="title" type="text" [(ngModel)]="story.title" req/>
<label for="subtitle">Subtitle</label>
<input type="subtitle" [(ngModel)]="story.subtitle" name="subtitle" req>
<label for="name">Name</label>
<input type="name" [(ngModel)]="story.name" name="name" req>
<button (click)="addContent()">Add Content</button>
<div *ngFor="let content of story.contents">
<label for="type">Type</label>
<select name='type' [(ngModel)]="content.type" value="{{content.type}}">
<option value=''>Pick one</option>
<option value='text' selected="selected">text</option>
<option value='image'>image</option>
</select>
<label for="text">Text</label>
<textarea name="text" cols="50" rows="7" [(ngModel)]="content.text">{{content.text}}</textarea>
<label for="url">url</label>
<input name="url" type="text" value="{{content.url}}" [(ngModel)]="content.url">
</div>
<button type="submit">Edit</button>
</form>
</div>
In the console.log to display the story, the contents array appears fine. Even when I open devtools and check the HTML elements, the values are correct.
devtools showing the innerHTML values are all different
However the page itself has all these element with only the values of the last array item.
contarary to the devtools html, the page displays the last array values over and over
please help.
You are using template-driven forms. The problem is in the way you're registering the child controls using ngModel
and the name
attribute.
In your ngFor
you do:
<textarea name="text" [(ngModel)]="content.text">{{content.text}}</textarea>
So basically you're assigning the same name to all children.
Instead, you should do something like this:
<div *ngFor="let content of story.contents; index as i">
<!-- other elements -->
<label for="text">Text</label>
<textarea name="{{ 'text-' + i }}" [(ngModel)]="content.text">
{{ content.text }}
</textarea>
<!-- other elements -->
</div>
You may also find the last section of this article helpful.
Cheers.