Home > other >  Angular 13 - Data is accessible inside component, but does not show on the html page
Angular 13 - Data is accessible inside component, but does not show on the html page

Time:12-24

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">
  • Related