7

So I have a component that takes in a value from an object. I have the outer div subscribed to a behavior subject. When I update the behavior subjects value using next() the title of the container div updates but the inner component refuses to re-render. Am I doing something wrong here?

Here is the behavior subject in my controller, this is called in the ngOnInit method and the update method that is called on button click in the html:

ngOnInit() {
  this.selectedRole$.next({ name: 'Current Permissions', permissions: this.getUserPermissions()
}

showRoleDetails(role: any): void {
  this.selectedRole$.next(role);
}

here is the parent component html this is where I am using async to subscribe to the behavior subject. the selectedRole.name updates perfectly but the inner c-permissions-display does not re-render:

<div *ngIf="selectedRole$ | async as selectedRole" class="col-8">
  <h5 class="font-weight-medium mb-0 text-gray-500 mb-4 permissions-title">{{ selectedRole.name }}</h5>
  <div class="section-container">
    <c-permissions-display [permissions]="selectedRole.permissions"></c-permissions-display>
  </div>
</div>

here is the c-permissions-display component:

import { Component, OnInit, Input } from '@angular/core';
import { UtilityService } from 'src/app/canopy-common/services/utility.service';

@Component({
  selector: 'c-permissions-display',
  templateUrl: './permissions-display.component.html',
  styleUrls: ['./permissions-display.component.scss']
})
export class PermissionsDisplayComponent implements OnInit {

  @Input() permissions: any[];
  formattedPermissions: any[];

  constructor(
    private util: UtilityService
  ) { }

  ngOnInit() {
    this.formattedPermissions = this.formatPermissionsArray();
  }

  private formatPermissionsArray(): any {
    return stuff
  }
}

if I place a console log in the ngOnInit it calls once when the page loads but never again after calling next() on the behavior subject. I know I can get this to work if I implement OnChanges and then the ngOnChanges() method but I should not have to do that it should update and re-render on its own if its input changes value. Unless they changed that in angular 9

2
  • Why don't you use directly permissions into your child component ? Commented Jan 13, 2020 at 17:15
  • did you get an answer? Commented Oct 28, 2024 at 10:51

2 Answers 2

4

Instead of passing value to child component. you can pass observable to child component and subscribe inside child component so that whenver value changes in parent component child component get notified.

Try this

parent.component.html

<div *ngIf="selectedRole$ | async as selectedRole" class="col-8">
  <h5 class="font-weight-medium mb-0 text-gray-500 mb-4 permissions-title">{{ selectedRole.name }}</h5>
  <div class="section-container">
    <c-permissions-display [permissions]="selectedRole$"></c-permissions-display>
  </div>
</div>

child.component.ts

export class PermissionsDisplayComponent implements OnInit {

   @Input() permission = new BehaviorSubject(null);
   formattedPermissions: any[];

  constructor(
    private util: UtilityService
  ) { }

  ngOnInit() {
    this.permission.subscribe(permission=>{
        this.formattedPermissions = this.formatPermissionsArray();
    })

  }

  private formatPermissionsArray(): any {
    return stuff
  }
}
Sign up to request clarification or add additional context in comments.

Comments

1

I think i remember it is because selectedRole.permission is an array and angular can't know if a value inside this array is changing or not.

So to make the array refresh too, you must overwrite the permission array with a new one. Something like selectedRole.permission = [new permission array ].

This way angular should be able to detect the change and refresh the view.

1 Comment

even if I change the input of the permissions component to be the selectedRole it still won't update

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.