2

I have two components HomePageComponent and StudentResultsComponent. I have an input in HomePageComponent that when I type, I want the value to be in my StudentResultsComponent input.

I thought of creating a separate component for the input and calling them in both components, but the value is not being updated in my StudentsResultsComponent when I start typing in HomePageComponent. Heres my code:

Career-Search-Component.html

<input
  #input
  type        ="text"
  id          ="searchInput"
  class       ="input-student-search validate filter-input"
  placeholder ="Search by a career (Software Engineer,Web Developer,Geologist, Geogropher etc.)"
  [(ngModel)] ="query"
>

Career-Search.component.ts

import {Component,OnInit,Input,EventEmitter} from '@angular/core';
@Component({
  selector: 'career-search',
  templateUrl: 'career-search.component.html'
})
export class CareerSearchComponent implements OnInit {
  @Input() public query: string;
  constructor() {}

  ngOnInit() {}

}

HomePageComponent.component.html

<career-search></career-search>
<button class="submit" [routerLink]="['/students']">Search</button>

Students-result.component.html

<career-search></career-search>

The reason why i need to pass the data from the homepage component is because I can then use the data to query it and show results based on the value being passed from the other component.

Please help.

Thanks

7
  • What is this career-search component then? And you are not showing any of your templates.. where you type in your home component and also not template in your students result component where you expect to get the input? And what is the relationship between these two components? same level components, or parent child or what? :) Commented Mar 15, 2017 at 16:48
  • Sorry I misunderstood you. So basically what I want is to get the value of the input typed in HomePageComponent and pass it to my input inside another component called StudentResultsComponent using ngModel @AJT_82 Commented Mar 15, 2017 at 16:52
  • Ooookay... but where is the code for that input typed in HomePageComponent and how does the template (and ts code) look like? And what is the relationship between these components? This is also important information. If they are parent and child, you can use Input() if they are not parent and child, you need to use a shared service :) Commented Mar 15, 2017 at 16:55
  • This is a good page to read how components can communicate with each other angular.io/docs/ts/latest/cookbook/component-communication.html Commented Mar 15, 2017 at 16:59
  • Oh sorry about that. There is nothing important to show in the ts of HomePage. The relationship between them is just two different components. They are not children or what not. @AJT_82 Commented Mar 15, 2017 at 17:01

1 Answer 1

4

If your two components don't have any other connection the only way I know of is to use a service. The link provided by AJT_82 has an example for it and here is the smallest example I can think of:

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

@Injectable()
export class InputService {

  public inputEvents: EventEmitter<string> = new EventEmitter();

  public inputChanged(val: string) {
    this.inputEvents.emit(val);
  }
}

@Component({
  selector: 'observer',
  template: `
    <p>Input value: {{ myValue }}</p>
`
})
export class ObserverComponent implements OnDestroy {

  private myValue: string;
  private subscription: Subscription;

  constructor(private service: InputService) {
    this.subscription = this.service.inputEvents.subscribe((newValue) => {
      this.myValue = newValue;
    })
  }

  ngOnDestroy(): void {
    this.subscription.unsubscribe();
  }
}

@Component({
  selector: 'observable',
  template: `
    <input [(ngModel)]="inputValue" />
`
})
export class ObservableComponent {

  private _inputValue: string;

  constructor(private service: InputService) {}

  public get inputValue(): string {
    return this._inputValue;
  }

  public set inputValue(val: string) {
    this._inputValue = val;
    this.service.inputChanged(val);
  }
}

@Component({
  selector: 'app-root',
  template: `

    <observable></observable>
    <observer></observer>

`
})
export class AppComponent {
}

Explanation:

The Observable Component stores the input-Value via two-way data binding. Within the setter we not only store the value, but also tell the service the value has changed. The service will then emit an inputChanged event, which the Observer subscribes to. It can then use the value however it likes.

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

1 Comment

Thank you for your explanation and for your example. It was exactly what I wanted.

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.