Hey I am trying to bind some data (onclick) .
I can tell the data binding is working because I have placed some interpolation in the HTML to display the new value. My issue is that I am trying to use that same data to update the string of an API.
The binding works but the string to the API never gets updated. Why is that so ?
Here is my Code
This is the component where the data is coming from.
HTML
<nav class="navbar nb" role="navigation" aria-label="main navigation" >
<button class="nav-button" (click)='myFunction()'>button</button>
</nav>
<app-info [item]="currentItem"></app-info>
TS
import { Component, EventEmitter, Output, Input } from '@angular/core';
import { ValueService } from './value.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
myFunction() {this.currentItem = 'foo'; }
currentItem = '';
}
This is the component where the data is passed to.
import { Component, EventEmitter, OnInit, Input, Output } from '@angular/core';
import {MatTabsModule} from '@angular/material/tabs';
import {MatListModule} from '@angular/material/list';
import { Observable } from 'rxjs';
import {HttpClient, HttpHeaders} from '@angular/common/http';
import { size } from 'lodash';
@Component({
selector: 'app-info',
templateUrl: './info.component.html',
styleUrls: ['./info.component.css']
})
export class InfoComponent implements OnInit {
@Input() item = '';
linkUrl = 'http//api.data'+this.item+'rest.of.api';
constructor(private http: HttpClient ) { }
ngOnInit(){
this.http.get(this.linkUrl).subscribe(link => {this.linkData = [link as any];});
}
}
The Data Binding works when the link URL in ngOnInit is not a factor. I was expecting the link to be updated one the button was clicked.
How can I fix this issue ?
3
Answers
I figured the issue. As stated by @Johnalternate the linkUrl is a string and changes to that string needs to be update. ngOnInit fires on first and subsequent loads of the component. If all is already static the update won't go through.
So the best bet was to use a different lifecycle hook called
OnChanges()
. With that hook all seems to update on the click of a button.In your InfoComponent you are setting the value of linkUrl when the component is being instanciated, so
linkUrl
is build using the available value for item, which at that moment is''
. Since linkUrl is just a string, there is no way it will update after item is updated.You can use a function or a getter that takes the value of item and builds the linkUrl for you, something like:
Components shouldn’t have the
HttpClient
dependency injected, that should be handled with a service. Looking at your code, it looks likeInfoComponent
is a dumb component, so the parent component, in this case,AppComponent
should be the one providing thelinkData
, for example:Service
Parent Component ts
Parent providing a value to child component
Child Component
If you really want to go with your approach, I suggest you do the following changes just in your
InfoComponent
:Every time
item
is changed,ngOnChanges
will detect that, and trigger the necessary logic, for this, it is recommended to change the change detection toonPush
.For more information about sharing data between components, I recommend reading the official docs