Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

angular 4: call a method from a different component

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?

like image 268
Sivvio Avatar asked Jul 19 '17 10:07

Sivvio


People also ask

How do I call Ngoninit from another component?

The short answer is to use ViewChild to call the function on component B.


2 Answers

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()

}
like image 191
Rahul Singh Avatar answered Sep 17 '22 16:09

Rahul Singh


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.

like image 31
snorkpete Avatar answered Sep 19 '22 16:09

snorkpete