Home > database >  How variables in component.ts is automatically updating without using an updateData()/ngOnit again i
How variables in component.ts is automatically updating without using an updateData()/ngOnit again i

Time:09-01

I am new to Angular. While implementing a function using service class in my component class, i got this logic issue. Below is the code-

Stackblitz link

app.module.ts

@NgModule({
  declarations: [
    AppComponent,
    AddUserComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    FormsModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

app.component.ts

import { UserService } from './services/user.service';
import {  Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
  providers: [UserService]
})
export class AppComponent implements OnInit {
  title = 'UserAvailabe';

  constructor(private userService: UserService) {
  }

  pusers: { name: string; status: string; }[] = [];

  ngOnInit() {
    this.pusers = this.userService.users;
    console.log("ngOnInit called");
  }    
}

app.component.html

<div >
  <app-add-user></app-add-user>
  <div  *ngFor="let user of pusers">
    <div >{{user.name}}</div>
    <div >{{user.status}}</div>
  </div>
</div>

add-user.component.ts

import { UserService } from './../services/user.service';
import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-add-user',
  templateUrl: './add-user.component.html',
  styleUrls: ['./add-user.component.css']
})
export class AddUserComponent implements OnInit {

  username: string = '';
  status: string = 'active';

  constructor(private userService: UserService) { }

  ngOnInit(): void {
  }

  addUser() {
    this.userService.addNewUser(this.username, this.status);
    console.log("addUser() called");
    console.log(this.userService.users);
  }

}

add-user.component.html

<div >
    <div >
        <input type="text" placeholder="Username" id="username" [(ngModel)]="username">
    </div>
    <div >
        <select name="status" id="status" [(ngModel)]="status">
            <option value="active">active</option>
            <option value="inactive">inactive</option>
        </select>
    </div>
    <div >
        <button (click)="addUser()">Create User</button>
    </div>
</div>

user.service.ts

export class UserService {

  constructor() { }

  users = [
    { name: 'John', status: 'active' },
    { name: 'Mark', status: 'inactive' },
    { name: 'Steve', status: 'active' }
  ]

  addNewUser(pname: string, pstatus: string) {
    this.users.push({ name: pname, status: pstatus });
  }
}

So, Initally using ngOnint(), pusers in app.component.ts get populated from service class. But when I add a new username and its status, the users in app.service.ts gets updated using addUser(). But how it is again updating the pusers in app.component.ts without calling the ngOnint() again / any other updateData() methods while running?

PS: Please forgive if my question is wrong. Thanks a lot for your help :)

CodePudding user response:

In javascript arrays and objects are passed by reference, not by value. Thus pusers is just referencing the memory location of users. To learn more read:

https://medium.com/nodesimplified/javascript-pass-by-value-and-pass-by-reference-in-javascript-fcf10305aa9c#:~:text=In Javascript objects and arrays follows pass by reference.&text=so if we are passing,of the object can change.

If you want to copy the value of an array instead of its reference, in ngOnInit you can just write:

this.pusers = [...this.userService.users];

and this will fix your problem

  • Related