DreadedHippy
DreadedHippy

Reputation: 96

How to transfer variables from a ts fie to another, angular

I defined a property here in my function

evs: string
...
openArticle(url){
    this.evs = url
    console.log(this.evs)
    this.navCtrl.navigateForward('/url-page')

  }

And I a trying to pass the value of 'this.evs' to another ts file and use its value but I do not know how to do this. I tried exporting it like this.

export const webpage = this.evs

but this.evs has no value until someone performs the openArticle function ad so I keep getting the error. "Cannot read property 'evs' of undefined"

What i need to do is tranfer the variable to the 'url-page' page and use the value of this.evs only after the openArticle function has bee called. How do I go about this?

Upvotes: 0

Views: 600

Answers (2)

Gauri Kesava Kumar
Gauri Kesava Kumar

Reputation: 474

  1. If the components have a parent/child relationship, You can share data between them via @Inpput() and @Output() decorators.

Sharing data from Parent to Child using @Input() :

<h3>Parent Component</h3>

<label>Parent Component</label>c
<input type="number" [(ngModel)]='parentValue'/>

<p>Value of child component is: </p>
<app-child [value]='parentValue'></app-child>

And in the child component, the 'parentValue' can be received as :

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

@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {

  @Input() value: number;
  constructor() { }

  ngOnInit() {
  }

}

Now, in the case of sending data from Child to Parent, we can use an @Output() event emitter. So the parent would have a function to receive the emitted data from child as :

parent-app.component.html 
    <app-child [value]="parentValue" (childEvent)="childEvent($event)"></app-child>

parent-app.component.ts

childEvent(event) {
console.log(event);
}

And, the child.component.ts would look like :

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

@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {

  @Input() PData: number;
  @Output() childEvent = new EventEmitter();
  constructor() { }
  onChange(value) {
    this.childEvent.emit(value);
  }

  ngOnInit() {
  }

}
  1. If the components do not have a parent/child relationship, a shared service can be used, say, SharedService which has a BehavioralSubject, that emits value from either component, and the other component can then catch the changed value.

Eg:

import { Injectable } from '@angular/core';
import { BehaviorSubject } from "rxjs/BehaviorSubject";

@Injectable()
export class SharedService {

  comp1Val: string;
  _comp1ValueBS = new BehaviorSubject<string>('');

  comp2Val: string;
  _comp2ValueBS = new BehaviorSubject<string>('');

  constructor() {
    this.comp1Val;
    this.comp2Val;

    this._comp1ValueBS.next(this.comp1Val);
    this._comp2ValueBS.next(this.comp2Val);
  }

  updateComp1Val(val) {
    this.comp1Val = val;
    this._comp1ValueBS.next(this.comp1Val);
  }

  updateComp2Val(val) {
    this.comp2Val = val;
    this._comp2ValueBS.next(this.comp2Val);
  }

And component1 as follows :

import { Injectable } from '@angular/core';
import { BehaviorSubject } from "rxjs/BehaviorSubject";

@Injectable()
export class SharedService {

  comp1Val: string;
  _comp1ValueBS = new BehaviorSubject<string>('');

  comp2Val: string;
  _comp2ValueBS = new BehaviorSubject<string>('');

  constructor() {
    this.comp1Val;
    this.comp2Val;

    this._comp1ValueBS.next(this.comp1Val);
    this._comp2ValueBS.next(this.comp2Val);
  }

  updateComp1Val(val) {
    this.comp1Val = val;
    this._comp1ValueBS.next(this.comp1Val);
  }

  updateComp2Val(val) {
    this.comp2Val = val;
    this._comp2ValueBS.next(this.comp2Val);
  }

Component 2 :

import { Component, AfterContentChecked } from '@angular/core';
import { SharedService } from "../../common/shared.service";

@Component({
  selector: 'app-component2',
  templateUrl: './component2.component.html',
  styleUrls: ['./component2.component.css']
})
export class Component2Component implements AfterContentChecked {

  comp1Val: string;
  comp2Val: string;

  constructor(private sharedService: SharedService) {
    this.sharedService.comp2Val = "Component 2 initial value";
  }

  ngAfterContentChecked() {
    this.comp1Val = this.sharedService.comp1Val;
  }

  addValue(str) {
    this.sharedService.updateComp2Val(str);
  }

}

You can find more on different types of subjects here

Upvotes: 0

srp
srp

Reputation: 763

As per my understanding you are trying to share data between two components. So choose one of them as per your requirements.

  1. Parent to Child: Sharing Data via Input().

  2. Child to Parent: Sharing Data via Output() and EventEmitter.

  3. Unrelated Components: Sharing Data with a Service.

This link will be helpful.

Upvotes: 1

Related Questions