简体   繁体   中英

How to properly transfer data between components? Angular

I need your help. I am practicing passing data between components. I am trying to transfer data between components using simple arrays and subjects. Unfortunately, I get an error when I want to add an element using the subject method. The error looks like this: Error trying to diff 'hello'. Only arrays and iterables are allowed Error trying to diff 'hello'. Only arrays and iterables are allowed

I have only 2 questions:

  1. What is my mistake, what did I do wrong?
  2. What is the best way to transfer data between components: to use services with simple arrays or to use subject or to use Input Output + EventEmmiter decorators?

Thank you very much

DataTransferService

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

@Injectable({
   providedIn: 'root'
})

export class DataTransferService {
   public array: any[] = [];
   public transferArray = new BehaviorSubject<any>([]);
}

ComponentOne

import {Component} from "@angular/core";
import {DataTransferService} from "../data-transfer.service";

@Component({
   selector: 'component-one',
   template: `<h1>component one</h1>
           <button (click)="sendData()">Send data array</button>
           <button (click)="sendDataTwo()">Send data subject</button`
})

export class ComponentOne {

constructor(public dataService: DataTransferService) {}

   sendData() {
      this.dataService.array.push(`hello` + 1)
   }

   sendDataTwo() {
      this.dataService.transferArray.next('hello');
   }

}

ComponentTwo

import {Component} from "@angular/core";
import {DataTransferService} from "../data-transfer.service";

@Component({
   selector: 'component-two',
   tepmlate: `<h1>component two</h1>
             <div>using array<div *ngFor="let element of elements">{{element}}</div></div>
             <div>using subject<div *ngFor="let subj of subjectElements">{{subj}}</div></div>`

export class ComponentTwo {
   public elements: any;
   public subjectElements: any;

   constructor(public dataService: DataTransferService) {
      this.elements = this.dataService.array;
      this.dataService.transferArray.subscribe(value => {
        this.subjectElements = value;
      })
    }
   }
}
  1. What is my mistake, what did I do wrong?

Ans: You need to push data into the array and then call the next method of the behaviour subject. Only then data will be pushed. Also either maintain an array with a subject, or a behaviour subject that stores an array. In the below example, I am using a behaviour subject that stores an array!

  1. What is the best way to transfer data between components: to use services with simple arrays or to use subject or to use Input Output + EventEmmiter decorators?

Simple parent child communication (child is inside parent) -> @Input @Output

Simple parent child communication but child shown inside parent using routing -> subject emitter pattern or share the values through a common service.

parent to distant child and vice versa, lots of components inbetween -> subject emitter pattern or share the values through a common service.


Change the code as below

DataTransferService

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

@Injectable({
   providedIn: 'root'
})

export class DataTransferService {
   public elementsArray = [];
   public transferArray = new BehaviorSubject<any>([]);
   public elementsArraySubject = new BehaviorSubject<any>([]);

   addNewData(data: any) {
       const arr = this.transferArray.getValue();
       arr.push(data);
       this.transferArray.next(data);
   }
}

ComponentOne

import {Component} from "@angular/core";
import {DataTransferService} from "../data-transfer.service";

@Component({
   selector: 'component-one',
   template: `<h1>component one</h1>
           <button (click)="sendData()">Send data array</button>
           <button (click)="sendDataTwo()">Send data subject</button`
})

export class ComponentOne {

constructor(public dataService: DataTransferService) {}

   sendData() {
      this.dataService.addNewData(`hello` + 1);
   }

   sendDataTwo() {
      this.dataService.elementsArray.push('hello');
      this.dataService.elementsArraySubject.next();
   }

}

ComponentTwo

import {Component} from "@angular/core";
import {DataTransferService} from "../data-transfer.service";

@Component({
   selector: 'component-two',
   tepmlate: `<h1>component two</h1>
             <div>using array<div *ngFor="let element of elements">{{element}}</div></div>
             <div>using subject<div *ngFor="let subj of subjectElements ">{{subj}}</div></div>`

export class ComponentTwo {
   public elements: any;
   public subjectElements: any;

   constructor(public dataService: DataTransferService) {
      this.dataService.transferArray.subscribe(value => {
        this.subjectElements = value;
      })
      this.dataService.elementsArraySubject.subscribe(() => {
        this.elements = this.dataService.elementsArray;
      })
    }
   }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM