So, I am learning Angular right now, and tried doing a CRUD Application. Almost everything works, except when trying to get data using ID, I can access all the data in the component.ts
file, but the same is not rendered into html file. Here is what I have tried :-
edit-to.component.ts
export class EditTodoComponent implements OnInit {
private tid: number = 0;
public Todo:TodoModel= null ;
public desc:string='';
public title:string='';
public id:number;
constructor(private route: ActivatedRoute, private http:HttpClient) { }
ngOnInit(): void {
this.route.paramMap.subscribe(all_params =>{
this.tid = parseInt(all_params.get('id'))
//console.log( all_params.get('id'))
//console.log( this.tid );
});
this.getTodoFromId(this.tid)
}
getTodoFromId(id){
//console.log("id=" id)
this.http.get<{data: any}>('http://localhost:3000/api/todos/get_todo_from_id/' id).subscribe((data) =>{
console.log("response in angular= \n");
this.Todo = data[0]
console.log(this.Todo.todo_title) //-> This one works
}
editOnSubmit(form:NgForm){
//something here
}
edit-todo.component.html
<div >
<form (ngSubmit)="editOnSubmit(todoForm)" #todoForm="ngForm">
<input type="text" id="todo_id" [(ngModel)]="id" name="todo_id" value="1">
<div >
<label for="todo_title" >Title</label>
<input type="text" id="todo_title" [(ngModel)]="title" name="title" value="{{ Todo.todo_title}}"> //-> This one does not work.
</div>
<div >
<label for="label" >Description</label>
<textarea id="todo_description" [(ngModel)]="desc" name="desc" ></textarea>
</div>
<button type="submit" >Edit To Do</button>
</form>
</div>
</div>
Separating out,
from edit-to.component.ts :-
console.log(this.Todo.todo_title)
works
but from edit-todo.component.html
<input type="text" id="todo_title" [(ngModel)]="title" name="title" value="{{ Todo.todo_title}}">
does not work
CodePudding user response:
it's because you have a ngModel and a value configured on same input field
in this situation the ngModel have priority on value attribute
to fix it you can initialize title in ngOnInit
this.title = this.Todo.todo_title;
in your case you wait reply from http request so the initialization after hte http reply :
getTodoFromId(id){
this.http.get<{data: any}>('http://localhost:3000/api/todos/get_todo_from_id/' id).subscribe((data) =>{
console.log("response in angular= \n");
this.Todo = data[0]
this.title = this.Todo.todo_title;
console.log(this.Todo.todo_title);
}
CodePudding user response:
Define a property of type BehaviorSubject.
isAvailableData = new BehaviorSubject<boolean>(true);
Then where you subscribe the data set it to true.
getTodoFromId(id){
//console.log("id=" id)
this.http.get<{data: any}>('http://localhost:3000/api/todos/get_todo_from_id/' id).subscribe((data) =>{
console.log("response in angular= \n");
this.Todo = data[0];
this.isAvailableData.next(true);
console.log(this.Todo.todo_title) //-> This one works
}
after that in your HTML add ngIf to col-md-12 div:
<div *ngIf="(isAvailableData | async)">
<form (ngSubmit)="editOnSubmit(todoForm)" #todoForm="ngForm">
<input type="text" id="todo_id" [(ngModel)]="id" name="todo_id" value="1">
<div >
<label for="todo_title" >Title</label>
<input type="text" id="todo_title" [(ngModel)]="title" name="title" value="{{ Todo.todo_title}}"> //-> This one does not work.
</div>
<div >
<label for="label" >Description</label>
<textarea id="todo_description" [(ngModel)]="desc" name="desc" ></textarea>
</div>
<button type="submit" >Edit To Do</button>
</form>
Also you made a mistake in your form the input should be like below:
And there is no need to define a property for id, title, ... These are the properties of todo object
<label for="todo_title" >Title</label>
<input type="text" id="todo_title" [(ngModel)]="Todo.todo_title" name="todo_title" #todo_title="ngModel">