2

I'm learning Angular, I have these components:

MainComponent.ts

import {Component} from 'angular2/core';
import {UsersTableComponent} from './UsersTableComponent';
import {UserAddComponent} from './UserAddComponent';

@Component({
    selector: 'main',
    templateUrl: '../app/views/mainView.html',
    directives: [UsersTableComponent, UserAddComponent]
})

export class MainComponent {
    constructor() {}
}

UserAddComponent.ts

import {Component} from 'angular2/core';
import {GenderPipe} from '../pipes/GenderPipe';

@Component({
    selector: 'userAdd',
    templateUrl: '../app/views/userAdd.html',
    pipes: [GenderPipe]
})

export class UserAddComponent {
    constructor() {}

    addUser() {
        alert(1);
    }
}

UserTableComponent

import {Component} from 'angular2/core';
import {UserServices} from '../services/UserServices';
import {User} from '../classes/User';
import {GenderPipe} from '../pipes/GenderPipe';

@Component({
    selector: 'usersTable',
    templateUrl: '../app/views/usersTable.html',
    pipes: [GenderPipe]
})

export class UsersTableComponent {
    users: Array<User>

    constructor(UserServices: UserServices) {
        this.users = UserServices.getUsers();
    }
}

on the UserAddComponent on addUser method I need to read some values from the template and update users though UserServices. When it is updated, I need to call a method from the UserTableComponent in order to refresh a table with the data added to the users.

How can I call a method in one component from another component?

2 Answers 2

4

Have the parent of both components hold the list of users in a property and pass it to both children components using @Input, that way both will react whenever the list changes:

https://angular.io/docs/ts/latest/api/core/Input-var.html

Alternative you can throw an event with @Output:

https://angular.io/docs/ts/latest/api/core/Output-var.html

Sign up to request clarification or add additional context in comments.

Comments

0

You could add an event (user added) in the user service. When the response is received from the user service (add an element), it can call the emit method of the corresponding event emitter. the UserTableComponent component can register on this event using the subscribe method to be notified when the event is fired.

Another approach would be to trigger this 'user added' event from the UserAddComponent component itself:

@Component({
  (...)
})
export class UserAddComponent {
  @Output() userAdded;

  constructor(private service:UserService) {
  }

  addUser() {
    // user is linked to a form for example
    this.service.addUser(this.user).subscribe(
      (addedUserData) => {
        this.userAdded.emit(addedUserData);
      }
  }
}

The other component (the table one) can use the event like this:

<add-user (user-added)="refreshTable()"></add-user>

Hope it helps you, Thierry

5 Comments

Super annoying when people downvote without leaving a comment why :-/
I don't know why I think its a valid alternative, I even mentioned it myself. But my feedback is that this way you are breaking the whole purpose of binding. It has its uses but if you were to emit and subscribe to each change between components why would you use a binding framework in the first place?
@Langley: I see exactly what you mean... We could add the response content into the list the array is bound on. The problem is that we could have observable and async pipe that are used to display the list...
But that observable can be anywhere, might as well be in the parent and feed the children with them right?
@Langley: Yes but I mean how to add new values in a loop for example that leverages the async pipe. Data were initially loaded from an HTTP request for example and then how to add an element to the list without executing again the HTTP request...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.