Fearghal
Fearghal

Reputation: 11447

Passing Parameter to Angular2 Component

I'm Learning Angular2 so be gentle... I have a basic Component which has a string array. I want to pass an integer to this component and have it return the string found at the index of that parameter.

E.g. myComponent[number]=1 returns string "second element".

My code so far is this:

import { Component } from '@angular/core';

@Component({
  selector: 'myComponent',
  template: 
    `<h1>Returned Value {{returnedString}}</h1>,`, 
  inputs:['number']
})
export class MyComponent  { 
  myStringArray: string[]; 
  returnedString: string;

  constructor(){
    this.myStringArray = ['First','Second','Third','Forth','Fifth','Sixth'];
    this.returnedString = 'number'+this.myStringArray['number'.valueOf()];
  }
}

I am calling this component as follows

<myComponent [number]=1></myComponent>

I print the value returned to the screen and get 'undefined'.

Any ideas folks?

Upvotes: 7

Views: 40197

Answers (6)

X Pahadi
X Pahadi

Reputation: 7463

It's quite simple. See this demo. Let's say you have two components parent and child. And you want to pass a variable to child and modify it there, say views.

On parent template:

<child [(views)]="views"></child>

On child component:

  @Input() views: number;
  @Output() viewsChange = new EventEmitter<number>();

  // Bind this function to button click or some events:
  updateViews() {
    this.views++;
    this.viewsChange.emit(this.views); // Emit the value to parent:
  }

Detail explanation: When you bind [(views)] in parent, it is acting as:

<child 
        [views]="views" 
        (viewsChange)="views = $event">
</child>

So, it is listening to viewsChange output function. Whenever, you do viewsChange.emit, the parent views get updated.

Gotcha: The output function should be precisely named $var + "Change". If you chose to name something else you will have to do:

<child 
            [views]="views" 
            (customEmitterFunction)="views = $event">
    </child> 

Upvotes: 1

Som
Som

Reputation: 1637

I had tough time to send string inputs. here is the correct way,

<myComponent [stringvar]="'string value'"></myComponent>

"string value" will not work. angular expecting object or number inside double quotes. string should be inside single quotes within double quotes "'string'"

Upvotes: 6

arpho
arpho

Reputation: 1646

In order to pass data from the child component to the father component you shuold set an Output parameter, to trigger the signal your component should implements the OnChanges interface, your component should be like this

    import { Component, Input,Output,EventEmitter,OnChanges,SimpleChanges } from '@angular/core';

@Component({
  selector: 'my-cmp',
  template: `
    <p>returnedString = {{ returnedString }}</p>
  `
})
export class MyComponent implements OnChanges {
  myStringArray: string[]  = ['First','Second','Third','Forth','Fifth','Sixth'];
  @Input() stringIndex: number;
 @Output() cardinalNumber:EventEmitter<string> = new EventEmitter<string>();// you define an Output, this will emit a signal that will received from the father Component

  ngOnChanges(changes:SimpleChanges) {
  // when the input changes we emit a signal
  this.cardinalNumber.emit(this.myStringArray[this.stringIndex]);
  }
  get returnedString(): string {
    if (this.stringIndex !== undefined) {
      return this.myStringArray[this.stringIndex];
    }
  }
}

then in the template of the father component you should insert :

    <my-cmp [stringIndex]=the parameter in father Component's controller
         (cardinalNumber)="method2beinvoked($event)">
</my-cmp>

method2beInvoked is the method in the father component that handles the message; or you could do like this:

    <my-cmp [stringIndex]=the parameter in father Component's controller
         (cardinalNumber)="parameter=$event")>
</my-cmp

where parameter is a parameter in the father's component controller

Upvotes: 0

AngularChef
AngularChef

Reputation: 14087

Here is another alternative. It demonstrates how to use a getter for returnedString. Less code needed than with ngOnChanges.

import { Component, Input } from '@angular/core';

@Component({
  selector: 'my-cmp',
  template: `
    <p>returnedString = {{ returnedString }}</p>
  `
})
export class MyComponent {
  myStringArray: string[]  = ['First','Second','Third','Forth','Fifth','Sixth'];
  @Input() stringIndex: number;

  get returnedString(): string {
    if (this.stringIndex !== undefined) {
      return this.myStringArray[this.stringIndex];
    }
  }
}

Upvotes: 1

Evans M.
Evans M.

Reputation: 1961

Since you want to bind to a custom property import Input and OnChanges from core and then implement as Input to create your custom property. The OnChanges just ensures your value gets updated when the bound value changes.

Remove the inputs key from your component decorator

import { Component, Input, OnChanges } from '@angular/core';

@Component({
  selector: 'myComponent',
  template: 
    `<h1>Returned Value {{returnedString}}</h1>,`
})
export class MyComponent  implements OnChanges { 
  myStringArray: string[];
  returnedString: string;
  @Input() inputNumber: number; 

  constructor(){
    this.myStringArray = ['First','Second','Third','Forth','Fifth','Sixth'];
    this.returnedString = 'number'+this.myStringArray[Number(this.inputNumber)];
  }

  ngOnChanges() {
    this.returnedString = 'number'+this.myStringArray[Number(this.inputNumber)];   
  }
}

Update your code usage to the following

<myComponent [inputNumber]="1"></myComponent>

Here is a sample plunker. https://plnkr.co/edit/S074zoVJ3ktQDKkcQgxe?p=preview

Upvotes: 11

Ali Baig
Ali Baig

Reputation: 3867

You need to create a number variable in your component too that will hold the value.

import {Component, OnInit} from '@angular/core';
@Component({
  selector: 'myComponent',
  template: 
    `<h1>Returned Value {{returnedString}}</h1>,`, 
  inputs:['myNum']
})
export class MyComponent implements OnInit { 
  myStringArray: string[] = ['First','Second','Third','Forth','Fifth','Sixth']; 
  returnedString: string;
  public myNum: number;  <= here is your variable

  ngOnInit() {
      //you can use this.myNum anywhere now like this
      this.returnedString = 'number '+ this.myStringArray[this.myNum];
  }

  constructor(){

  }
}

You may have to change the name of your input because number is a keyword.

Another Note: You have to use OnInit instead of constructor to start using your inputs. ngOnInit is an Angular2 lifecycle method that is called by Angular when it's done building the component and evaluated the bindings

Upvotes: 1

Related Questions