0

I'm a new in Angular and I have a problem: I need to use one variable from ComponentA in ComponentB So this is my code below (I need to use "favoriteSeason" input result in component "Result" Component A

   import { Component } from '@angular/core';
   import { FormBuilder, FormGroup, FormArray, FormControl, ValidatorFn }
   from '@angular/forms';
   import {MatRadioModule} from '@angular/material/radio';
   import { ResultComponent } from '../result/result.component';
   import { HostBinding } from '@angular/core';

   @Component({
     selector: 'app-answer-three',
     templateUrl: './answer-three.component.html',
     styleUrls: ['./answer-three.component.css']
   })
   export class AnswerThreeComponent  {

     disableBtn: boolean;
     favoriteSeason: string;
     seasons: string[] = ['Cheesburger', 'Cheesecake', 'Fondue', 'Pizza'];
       submit() {
       this.disableBtn = !this.disableBtn;
       const result = this.favoriteSeason;
       console.log(result);
     }

   }
  <div class="co">
    <mat-radio-group class="example-radio-group" [(ngModel)]="favoriteSeason" (ngSubmit)="submit()">
      <div class="form-check">
        <h1>Choose a food:</h1>
      </div>
      <mat-radio-button class="example-radio-button" *ngFor="let season of seasons" [value]="season">
        {{season}}
      </mat-radio-button>
    </mat-radio-group>
    <div class="example-selected-value">Your favorite food is: {{favoriteSeason}}</div>
    <nav>
      <div class="column">
        <button class="btn btn-primary" [disabled]="disableBtn" name="button" (click)="submit()">save

        </button>
        <button class="btn btn-primary" [disabled]="!disableBtn" name="button" (click)="submit()">
          <a routerLink="/result">Next</a>
        </button>
      </div>
    </nav>
  </div>

And I need to use the result of "favoriteSeason" in component Result Component B

   import { NgModule, Output } from '@angular/core';
   import { Component, OnInit, Input } from '@angular/core';
   import {Subject} from 'rxjs';
   import { Injectable } from '@angular/core';
   import { AnswerThreeComponent } from '../answer-three/answer-three.component';
   import { HostListener } from '@angular/core';


   @Component({
     selector: 'app-result',
     templateUrl: './result.component.html',
     styleUrls: ['./result.component.css'],
   })
   export class ResultComponent  {


   @Input () answer: AnswerThreeComponent;
   @Input () res: AnswerThreeComponent['submit'];

   @HostListener('click')
   click() {
    const result = this.answer.favoriteSeason;
    console.log(this.answer.favoriteSeason);
   }
   }

But i received an error - "can't find favoriteSeason name". What I do wrong? Thank you for any help and sorry if I wrote this question wrong (it's my first time)

2 Answers 2

2

Sanchit Patiyal's answer is correct, but I would like to elaborate on that.

When you use the @Input() decorator on a component's field, that means that you now can set that variable in a parent component's template. Consider the following example:

Component A:

@Component({
  selector: 'aComponent',
  templateUrl: './a.component.html'
})
export class AComponent {
  inputValue: string;
  //doesn't matter what you do here
}
<input [(ngModel)]="inputValue">
<bComponent [inputValue]="inputValue">
</bComponent>

Component B:

@Component({
  selector: 'bComponent',
  templateUrl: './b.component.html'
})
export class BComponent {
  @Input() inputValue: string;
  //this variable will be set by the parent component
}
<h1>{{inputValue}}</h1>

This is an example of one-way data flow, meaning that the data only flows into the component B. Now if you need to get some data out of the component, you need to use @Output() decorator, which uses an EventEmitter to emit events out to the parent component when something happens. Let's introduce the third component, cComponent:

@Component({
  selector: 'cComponent',
  templateUrl: './c.component.html'
})
export class CComponent {
  @Output() output: EventEmitter<string>;
  
  private counter: number;
  
  click() {
    this.output.next(counter++);
  }
}
<button (click)="click()">Click me!</button>

...and then edit our AComponent like this:

@Component({
  selector: 'aComponent',
  templateUrl: './a.component.html'
})
export class AComponent {
  inputValue: string;
  
  buttonClicked(event: string) {
    this.inputValue = event;
  }
}
<cComponent (output)="buttonClicked($event)"></cComponent>
<bComponent [inputValue]="inputValue"></bComponent>

So, to recap, the component's output works just like other events (say (click) or (focus)), and can be used to get the data out of the component. HOpe this helps ;)

Welcome, by the way!

1
  • Thank you for the example - now I understand why the code was not working!
    – Julie R
    Commented Jul 13, 2018 at 7:02
1

You can use RxJS BehaviorSubject for this. In this case we create a private BehaviorSubject that will hold the current value of the message which can be set in one component and get in other one. Follow this link for the tutorial.

Sharing Data Between Angular Components

3
  • You can share data between angular components via services (both have access to the same instance) or via their parent component (if they have the same parent).
    – SirDieter
    Commented Jul 12, 2018 at 14:51
  • Yeah that depend if they have same parent but I don't see any relation between components in the question asked that's why shared the link :) Commented Jul 12, 2018 at 14:53
  • 1
    I didn't actually want to write this comment, was on mobile and thought this was the answer field :D It should have been an answer but I accidentally sent it too early
    – SirDieter
    Commented Jul 12, 2018 at 15:00

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.