Angular 2, Cant able to access a variable in one Component from another Component

balajivaishnav picture balajivaishnav · Apr 11, 2017 · Viewed 16.1k times · Source

Sorry if this is a duplicated question, I have searched solution throughout the Web can't able to find any so am posting it, Am trying to access a variable from one component inside another component

What I have Tried

I have created a model of object type and have set the value inside a component A method, and tried to access that model object from component B so that I can set the value for the Component B Elements, but getting object as undefined

Problem

Component A is loaded first in browser, where it contains a table on click of the table row am getting the row data as object and setting that object to a Model which contains a similar structure object and I can able to get the object value in Component, whereas I tried to call the model from a Component B so that I can access the object value. but am getting the object value as undefined this is due to the Component B is a Modal which is Called inside the Component A Template.

Component A

 public rowSelected:boolean = true;
 constructor(public users : User ) {}
  getRowData(rowIndex: number, rowData: any): void { 
        this.rowSelected = $(rowIndex).hasClass('selected');
        console.log(rowData);
        this.users= rowData.FirstName;
        console.log(this.users); // can able to get the object value
    }

Component A Template

<div bsModal #editUserModal="bs-modal" class="modal fade" role="dialog" aria-hidden="true">
    <div class="modal-dialog modal-lg">
        <div class="modal-content">
            <div class="modal-header">
                <button class="close" aria-label="Close" type="button" (click)="editUserModal.hide()">
                    <span aria-hidden="true">&times;</span>
                </button>
                <h5 class="modal-title"><b>Edit User</b></h5>
            </div>
            <div class="modal-body">
                <componenetB #edituserDiv></componenetB>
            </div>
            <div class="modal-footer">
                <button class="btn btn-primary btn-sm  confirm-btn gap0" type="button" (click)="edituserDiv.EditUserSubmit()">Submit</button>
                <button type="button" class="btn btn-default btn-sm gap-left10 gap0" type="button" (click)="editUserModal.hide()">Close</button>
            </div>
        </div>
    </div>
</div>

Model

export class User {
    UserName: any
    Password: any
    FirstName: any
    MiddleName: any
    LastName: any
    Status: any
    Locked: any
    Active: any
    CreatedOn: any
    LastModified: any

}

Component B

export class Component B   { 

    constructor(public userz : User) {     
console.log(this.userz) // Object Value is Undefined
    }

}

Please help me to resolve this issue, thanks in advance

Answer

AJT82 picture AJT82 · Apr 11, 2017

Use @Input when you want to pass data from parent to child. Here I assume users is an array. If not, adjust the type accordingly.

So in your parent template:

<componenetB [users]="users"></componenetB>

From your child (component B), do not inject User in constructor. Use @Input instead:

export class Component B   { 
    @Input users: User[];

    constructor() { }
}

So that you do not get undefined error if the users is actually set later, just instantiate the users in your parent, so that it won't be undefined, while it waits for values to be set:

users: User[] = [];

Here is a demo, which simulates the values of users are set at a later point. Just click the button and the values will appear in child, values that are set in the parent.

Plunker