I have two separate routes. One is products and the other is products-cart. I want to use a common ts file for these two to keep the information of the products and the basket in the form of an array. But i am facing a problem. I can't make any changes or transfers. When I add something to the cart array, the information I pull from the product-cart does not change, it always stays empty. They said that I would resolve this with observable, but I was not successful. what I want is that there will be 3 products and when I add them from localhost:4200/products I can see them in localhost:4200/products/product-cart but these are two separate routes. Note (urls are for pictures)
data.service.ts
import { Injectable } from "@angular/core";
import { Product } from "./product";
@Injectable()
export class DataService{
productsData:Array<Product>=[
{name:'Tomato',total:10, url:'https://migrostvstr.blob.core.windows.net/migrostv/2021/08/domates-kg-c7462d-1650x1650-1.jpg'},
{name:'Patato',total:27, url:'https://migros-dali-storage-prod.global.ssl.fastly.net/sanalmarket/product/28303000/patlican-kemer-kg-2ac52c-1650x1650.jpg'},
{name:'Garlic',total:20, url:'https://migros-dali-storage-prod.global.ssl.fastly.net/sanalmarket/product/28293383/28293383-874ca9-1650x1650.jpg'}
];
productscard:Array<Product>=[];
constructor(){}
}
products.component.ts
import { Component, OnInit,Output } from '@angular/core';
import { EventEmitter } from '@angular/core';
import { DataService } from '../data.service';
import { Product } from '../product';
@Component({
selector: 'app-products',
templateUrl: './products.component.html',
styleUrls: ['./products.component.css']
})
export class ProductsComponent implements OnInit {
constructor(private data:DataService) { }
ngOnInit() {
console.log(this.data.productsData)
}
getItems(value){
}
}
product-cart.components.ts
import { Component, OnInit } from '@angular/core';
import { Input } from '@angular/core';
import { Product} from '../product';
import { DataService } from '../data.service';
@Component({
selector: 'app-product-cart',
templateUrl: './product-cart.component.html',
styleUrls: ['./product-cart.component.css']
})
export class ProductCartComponent implements OnInit {
constructor(private datacart:DataService) { }
ngOnInit (){
console.log(this.datacart.productscard)
}
}
CodePudding user response:
data.service:
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
export interface Product {
name: any;
total: any;
url: any;
}
@Injectable({
providedIn: 'root',
})
export class DataService {
productsCart: Product[] = [];
productsCart$ = new BehaviorSubject<Product[]>([]);
productsData: Array<Product> = [
{
name: 'Tomato',
total: 10,
url: '...',
},
{
name: 'Patato',
total: 27,
url: '...',
},
{
name: 'Garlic',
total: 20,
url: '...',
},
];
addToCart(product: Product): void {
this.productsCart.push(product);
this.productsCart$.next(this.productsCart);
}
}
ProductsComponent:
import { Component, OnInit } from '@angular/core';
import { DataService, Product } from '../data.service';
@Component({
selector: 'app-products',
templateUrl: './products.component.html',
styleUrls: ['./products.component.scss'],
})
export class ProductsComponent implements OnInit {
constructor(private service: DataService) {}
ngOnInit() {
console.log(this.service.productsData);
}
addToCart() {
const product = {
name: 'Tomato',
total: 10,
url: '...',
};
this.service.addToCart(product);
}
}
ProductCartComponent:
import { Component, OnInit } from '@angular/core';
import { DataService } from '../data.service';
@Component({
selector: 'app-product-cart',
templateUrl: './product-cart.component.html',
styleUrls: ['./product-cart.component.scss'],
})
export class ProductCartComponent implements OnInit {
constructor(private service: DataService) {}
ngOnInit() {
this.service.productsCart$.subscribe((data) => {
console.log(JSON.stringify(data));
});
}
}
CodePudding user response:
All right, make sure you added the service in your module providers (if you have one module it will be the appModule) in your service add:
//RxJs BehaviorSubject to use initiation value
productsDataEmitter: BehaviorSubject<Array<Product>>
=new BehaviorSubject([
{name:'Tomato',total:10, url:'https://migrostvstr.blob.core.windows.net/migrostv/2021/08/domates-kg-c7462d-1650x1650-1.jpg'},
{name:'Patato',total:27, url:'https://migros-dali-storage-prod.global.ssl.fastly.net/sanalmarket/product/28303000/patlican-kemer-kg-2ac52c-1650x1650.jpg'},
{name:'Garlic',total:20, url:'https://migros-dali-storage-prod.global.ssl.fastly.net/sanalmarket/product/28293383/28293383-874ca9-1650x1650.jpg'}
]);
// add this fuction to emit the data:
emitProductsData(products:Array<Product>){
this.this.productsDataEmitter.next(products);
}
Now in any of your components:
constructor(private data:DataService) { }
// if you want to get the data:
this.data.productsDataEmitter.subscribe(products=>{
console.log('the data array is', products);
});
//if you want to update the data use:
let newData: Array[Product] = [];
this.data.emitProductsData(newData);
if you want to read and then update the same subscribed data make sure you do it inside the subscribe scope:
this.data.productsDataEmitter.subscribe(products=>{
console.log('the data array is', products);
let product:Product = new Product();
let newData: Array<Product> = [...products,product];
this.data.emitProductsData(newData);
});