I have 2 sibling components, I am doing an http request in one component, and if a particular condition happens, it should make another http request, written in another component. So I should be able to call the method within the first component.
this is the first component:
import { Component, OnInit, Inject } from '@angular/core';
import { Http } from '@angular/http';
import { SendCardComponent } from '../send-card/send-card.component';
@Component({
selector: 'app-input-field',
templateUrl: './input-field.component.html',
styleUrls: ['./input-field.component.css'],
})
export class InputFieldComponent implements OnInit {
value = '';
output = '';
@Inject(SendCardComponent) saro: SendCardComponent;
constructor(private http : Http) { }
onEnter(value: string) {
this.value = value;
this.http.post('http://localhost:5000/APIconversation/', {"val":value})
.map(response=>response.json())
.subscribe(
data => {
this.output = data.result.fulfillment.speech,
if(data.result.fulfillment.speech == 'test'){
saro.sendCard('done', '1' );
}
});
}
I'm trying to call sendCard() defined in sendCardComponent, from InputFieldComponent which looks like this:
import { Component, OnInit } from '@angular/core';
import { Http } from '@angular/http';
@Component({
selector: 'app-send-card',
templateUrl: './send-card.component.html',
styleUrls: ['./send-card.component.css']
})
export class SendCardComponent implements OnInit {
constructor(private http : Http) { }
ngOnInit() {
}
output = '';
sendCard(value:string, id:number){
this.http.post('http://localhost:5000/APIconversation/', {"val":value})
.map(response=>response.json())
.subscribe(
data => {
this.output = data.result.fulfillment.messages[1].payload.options[id].type = $('#'+(id+1)+'>span').html();
});
} //sendCard
}
I get an error when calling saro.sendCard:
[ts] cannot find name 'saro'
What am I doing wrong?
The short answer is to use ViewChild to call the function on component B.
Create a instance of SendCardComponent in the InputFieldComponent
import { Http } from '@angular/http';
import { SendCardComponent } from '../send-card/send-card.component';
export class InputFieldComponent{
//your other variables and methods
constructor(private http : Http) { }
let saro = new SendCardComponent(this.http);
saro.sendCard()
}
You have 2 issues to address.
The first is that if you want to use Dependency Injection, your components need to have a parent-child relationship. So, in your case, if InputFieldComponent
is a child of SendCardComponent
, then you can use simple (constructor) dependency injection to get an instance of the parent SendCardComponent
from the InputFieldComponent
.
And that brings us to the second issue - the implementation. If I wanted to do the above, then I'd end up with:
export class InputFieldComponent implements OnInit {
value = '';
output = '';
constructor(private http : Http, private saro: SendCardComponent) { }
onEnter(value: string) {
this.value = value;
this.saro.methodOnSendCardComponent();
......
If the other relationship existed - where InputFieldComponent
is a parent of SendCardComponent
, then you can use @ViewChild
to get your instance of SendCardComponent
from InputFieldComponent
.
However, as noted, both of the above methods require you to change your view hierarchy. If the two components NEED to stay as siblings, then neither of the above would work.
Thinking it through further though, if you only need access to SendCardComponent
to use logic (i.e. methods) from it, why not abstract that logic to a service, and then you can use that service anywhere in your hierarchy? This bypasses your present problem quite neatly, and is sound advice in general. Honestly, your components should focus their behaviour on higher level concerns and 'outsource' as much as they reasonably can to services anyway.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With