Why my data on front-end Angular is not getting updated instantly as I am updating from API, I need to refresh the page then it is getting updated?

47 views Asked by At

Why my data on front-end Angular is not getting updated instantly as I am updating the roomList from API, the API is working fine the result is also updating but, I need to refresh the page then it is getting updated.Why is it so, I am new to Angular so not able to figure out how to solve this? I am using Angular version 17.

This is my room.component.ts

update() {
  const extraRoom: RoomList = {
    roomNumber:2,
    roomType: 'tory',
    amenities: 'Gas,CoolerKitchen',
    price: 300,
    photos: 'https://imagfine.jpg',
    checkinTime: '17-09-2002',
    checkoutTime: '02-Nov-2021',
    rating: 1,
   
  };
  this.roomsService.updateRooms(extraRoom.roomNumber,extraRoom).subscribe((data)=>{const idx=data.roomNumber;
 this.roomList.forEach((value,index)=>{
//  this.updateArray(data);
// this.roomList.push(extraRoom);
this.roomList[data.roomNumber].roomType =data.roomType;
this.roomList[data.roomNumber].amenities= data.amenities;
this.roomList[data.roomNumber].price =data.price;
this.roomList[data.roomNumber].photos = data.photos;
this.roomList[data.roomNumber].checkinTime = data.checkinTime;
this.roomList[data.roomNumber].checkoutTime = data.checkoutTime;
this.roomList[data.roomNumber].rating = data.rating;
 });

This is my service file

 updateRooms(id:number,room:RoomList){
    return this.http.put<RoomList>(`/api/hotel/${id}`,room);
  }

I am expecting the data to be updated instantly as soon as I clicked the edit button, but it is not happening instead of that when I am clicking on the edit room button there is no updation but when I am refreshing the page then the changes are shown.

This is my rooms.component.ts file.

import {
  AfterViewChecked,
  AfterViewInit,
  Component,
  DoCheck,
  OnInit,
  QueryList,
  SkipSelf,
  ViewChild,
  ViewChildren,
} from '@angular/core';
import { Room, RoomList } from './rooms';
import { CommonModule } from '@angular/common';
import { RoomsListComponent } from '../rooms-list/rooms-list.component';
import { HeaderComponent } from '../header/header.component';
import { RoomsService } from './services/rooms.service';
import { Observable } from 'rxjs';

@Component({
  selector: 'hinv-rooms',
  standalone: true,
  templateUrl: './rooms.component.html',
  styleUrl: './rooms.component.scss',
  imports: [CommonModule, RoomsListComponent, HeaderComponent],
})
export class RoomsComponent
  implements DoCheck, OnInit, AfterViewInit, AfterViewChecked
{
  update() {
    const extraRoom: RoomList = {
      roomNumber:2,
      roomType: 'tory',
      amenities: 'Gas,CoolerKitchen',
      price: 300,
      photos: 'https://imagfine.jpg',
      checkinTime: '17-09-2002',
      checkoutTime: '02-Nov-2021',
      rating: 1,
     
    };
    this.roomsService.updateRooms(extraRoom.roomNumber,extraRoom).subscribe((data)=>{const idx=data.roomNumber;
   this.roomList.forEach((value,index)=>{
  //  this.updateArray(data);
  // this.roomList.push(extraRoom);
  this.roomList[data.roomNumber].roomType =data.roomType;
  this.roomList[data.roomNumber].amenities= data.amenities;
  this.roomList[data.roomNumber].price =data.price;
  this.roomList[data.roomNumber].photos = data.photos;
  this.roomList[data.roomNumber].checkinTime = data.checkinTime;
  this.roomList[data.roomNumber].checkoutTime = data.checkoutTime;
  this.roomList[data.roomNumber].rating = data.rating;
   });
    });
  }
updateArray(newitem:RoomList){
  this.roomList[newitem.roomNumber].roomType = newitem.roomType;
  this.roomList[newitem.roomNumber].amenities= newitem.amenities;
  this.roomList[newitem.roomNumber].price = newitem.price;
  this.roomList[newitem.roomNumber].photos = newitem.photos;
  this.roomList[newitem.roomNumber].checkinTime = newitem.checkinTime;
  this.roomList[newitem.roomNumber].checkoutTime = newitem.checkoutTime;
  this.roomList[newitem.roomNumber].rating = newitem.rating;
}
  constructor(@SkipSelf()private roomsService:RoomsService){

  }
  ngAfterViewInit(): void {
    console.log(this.headerComponent);
    // this.headerComponent.title = 'Hello my name is Garima';
    this.headerChildrenComponent.last.title = 'last title';
    this.headerChildrenComponent.get(0);

  }

  ngAfterViewChecked() {
    console.log('after view checked');
  }
  title: string = 'Hotel Amenities';
  stream=new Observable(observer =>{
    observer.next('user1');
    observer.next('user2');
    observer.next('user3');
    observer.complete();
  });
  AddRoom() {
    const extraRoom: RoomList = {
      roomNumber:8,
      roomType: 'Deluxe Room',
      amenities: 'Air Conditioner, Free Wi-fi, TV, Bathroom, Kitchen',
      price: 400,
      photos: 'https://image.jpg',
      checkinTime: '11-Nov-2021',
      checkoutTime: '12-Nov-2021',
      rating: 7,
     
    };
    //this.roomList.push(extraRoom);
    // this.roomList = [...this.roomList, extraRoom];
    // Subscribing to post call and adding the newly creted data to our table
    this.roomsService.addRooms(extraRoom).subscribe((data)=>{
      console.log(data+"the newly added record is....");
      this.roomList = [...this.roomList, data];
    });
  }
  selectedRoom!: RoomList;
  selectRoom(room: RoomList) {
    console.log(room);
    this.selectedRoom = room;
  }
  hideRooms: boolean = true;
  role: any;
  toggle() {
    this.hideRooms = !this.hideRooms;
    this.title = 'Room List Of Rooms Available';
  }
  hotelName: string = 'Rddisson Blue';
  numberOfRooms: number = 10;
  rooms: Room = {
    totalRooms: 20,
    availableRooms: 10,
    bookedRooms: 5,
  };
  ngDoCheck(): void {
    console.log('On change is called...');
  }
  roomList: RoomList[] = [];
  @ViewChild(HeaderComponent) headerComponent!: HeaderComponent;
  ngOnInit(): void {
    this.stream.subscribe({
      next:(value) => console.log(value),
      complete:()=>console.log('complete'),
      error:(err)=>console.log(err),
    });
    this.stream.subscribe((data) => console.log(data));
    this.stream.subscribe((data) => console.log(data));
    console.log(this.headerComponent);
    // 
    console.log(this.roomsService.getRooms());
    this.roomsService.getRooms().subscribe(rooms =>{
      this.roomList=rooms;
     
    });
   
  }
  @ViewChildren(HeaderComponent)
  headerChildrenComponent!: QueryList<HeaderComponent>;
}
[![This is how my frontend looks](https://i.stack.imgur.com/eImmJ.png)](https://i.stack.imgur.com/eImmJ.png)
2

There are 2 answers

1
Ajish Kumar On

Try to use 2 way binding. This will update the data in the frontend when the variable is updated i.e, [(ngModel)]. Let me know if more info is required or if it doesn't work.

0
Alpine A110R On

It seems that your view is not updated after editing roomList.

this.roomsService.updateRooms(extraRoom.roomNumber,extraRoom).subscribe( … 

It’s the change detector issue, I think that angular does not run change detection.

One of the solutions is to call ChangeDetectorRef when you subscribe to the observable.

You must force to re-render your view with this.cd.detectChanges(); after fetching new data.

The detectChanges method will run change detection on the component and an update will be performed.

Try:

constructor(…, private cd: ChangeDetectorRef) {}


this.roomsService.updateRooms(extraRoom.roomNumber,extraRoom).subscribe((data)=>{

   const idx = data.roomNumber;

   this.roomList.forEach((value,index)=>{
    // this.updateArray(data);
    // this.roomList.push(extraRoom);

    this.roomList[data.roomNumber].roomType =data.roomType;
    this.roomList[data.roomNumber].amenities= data.amenities;
    this.roomList[data.roomNumber].price =data.price;
    this.roomList[data.roomNumber].photos = data.photos;
    this.roomList[data.roomNumber].checkinTime = data.checkinTime;
    this.roomList[data.roomNumber].checkoutTime = data.checkoutTime;
    this.roomList[data.roomNumber].rating = data.rating;
   });

   this.cd.detectChanges();

});

Another approach without using forEach :

 ..
const indexToUpdate = this.roomList.findIndex(item => item.roomNumber === data.roomNumber);
this.roomList[indexToUpdate] = data;
 ..