[SOLVED] Why is @Input property standardLinks been overwritten?

Issue

I’m currently working on a footer, where I want to display dynamically some links. The standard links should switch accordingly to the property company (which works just fine), but I also want them to change, if they are passed explicitly in the footer.ts file (see property customizedLinks).
Apparently the @Input property standardLinks in the links.component.ts file seems to be overwritten, so that the links won’t switch when passed explicitly.

Do you have any idea, how to solve this?

Here is my code:

link.component.ts

import {Component, Input, OnChanges, OnInit, SimpleChanges} from '@angular/core';
import {Link} from "../models/link.model";

@Component({
  selector: 'app-links',
  template: `
    <div *ngFor="let link of standardLinks">
      <a [href]="link.url">{{ link.name }}</a>
    </div>
  `,
  styleUrls: ['./links.component.css']
})
export class LinksComponent implements OnInit, OnChanges {
  @Input() company: 'a' | 'b' = 'a';
  @Input() standardLinks: Link[] = [];


  ngOnInit(): void {
    this.updateFooterLinks();
  }

  ngOnChanges(changes: SimpleChanges): void {
    if (changes.company) {
      this.updateFooterLinks()
    }
  }

  private updateFooterLinks() {
    if (this.company === 'b') {
      this.standardLinks = [
        new Link('Link 1b', 'blabla.com'),
        new Link('Link 2b', 'blabla.com'),
        new Link('Link 3b', 'blabla.com'),
      ];
    } else {
      this.standardLinks = [
        new Link('Link 1a', 'blabla.com'),
        new Link('Link 2a', 'blabla.com'),
        new Link('Link 3a', 'blabla.com'),
      ]
    }
  }

}

footer.component.html

<div class="row">
  <div class="col">
    <h1>Footer</h1>
  </div>
</div>
<div class="container">
  <div class="row">
  <div class="col">
        <h2>Legal 1</h2>
    </div>
  </div>
  <div class="container">
    <footer>
      <span>Brand 1</span>
      <app-links></app-links>
    </footer>
  </div>
</div>
<div class="container">
  <div class="row">
    <div class="col">
      <h2>Legal 2</h2>
    </div>
  </div>
  <div class="container">
    <footer>
      <span>Brand 2</span>
      <app-links
        [standardLinks]="customizedLinks"
      ></app-links>
    </footer>
  </div>
</div>
<div class="container">
  <div class="row">
    <div class="col">
      <h2>Legal 3</h2>
    </div>
  </div>
  <div class="container">
    <footer>
      <span>Brand 3</span>
      <app-links [company]="'b'"></app-links>
    </footer>
  </div>
</div>

footer.component.ts

import { Component, OnInit } from '@angular/core';
import {Link} from "../models/link.model";

@Component({
  selector: 'app-footer',
  templateUrl: './footer.component.html',
  styleUrls: ['./footer.component.css']
})
export class FooterComponent implements OnInit {
  customizedLinks : Link[] = [
    new Link('bla 1', 'blabla.com'),
    new Link('bla 2', 'blabla.com'),
    new Link('bla 3', 'blabla.com'),
  ]


  ngOnInit(): void {
  }

}

The expected behavior should be:

Footer

Legal 1

Brand 1
Link 1a
Link 2a
Link 3a

Legal 2

Brand 2
bla 1
bla 2
bla 3

Legal 3

Brand 3
Link 1b
Link 2b
Link 3b

Note that the code has been simplified.

Solution

Well, I see you’re overwritting the value explicitly w/o putting any condition:

enter image description here

In a nutshell, you can solve your problem by adding a condition to your updateFooterLinks function in ngOnInit as follows:

ngOnInit(): void {
  if (!this.standardLinks.length) {
    this.updateFooterLinks();
  }
}

OR

ngOnInit(): void {
  !this.standardLinks.length && this.updateFooterLinks();
}

Bonus: https://stackblitz.com/edit/angular-ivy-1cyz3z

One more thing.. Why you’re calling updateFooterLinks in ngOnChanges?

Answered By – Abder

Answer Checked By – Mary Flores (BugsFixing Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *