gather and handle data from the shared interface between different parts

I have two different paths. One is for products and the other is for products-cart. I want to use a shared ts file for both to store the product and cart information in an array. However, I am encountering an issue. I am unable to make any changes or transfers. Whenever I add something to the cart array, the data I retrieve from the product-cart remains empty. I was advised to resolve this using observables, but my attempts were unsuccessful. My goal is to have 3 products that can be added from localhost:4200/products and viewed in localhost:4200/products/product-cart even though these are separate routes. Note (URLs are for images)

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:'Potato',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)
  }

}

products.component.html

<div class="products">
  <div class="product-cards" *ngFor="let items of newData">
    <img class="icons" src="{{items.url}}">
    <div class="items-style">
      <div>
        Product name: {{items.name}}
      </div>
      <div>
        Quantity: {{items.total}}
      </div>
      <a class="add-icon"><i class="fas fa-cart-plus fa-2x icon"(click)="getItems(items)" ></i></a>
    </div>
  </div>
</div>

Answer №1

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));
    });
  }
}

Answer №2

Ensure that you have included the service in your module providers (if you are using a single module, it should be the appModule). In your service, add the following:

//RxJs BehaviorSubject for initializing 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'}
                              ]);

// include this function to emit the data:
emitProductsData(products:Array<Product>){
    this.this.productsDataEmitter.next(products);
  }

Now, in any of your components:

constructor(private data:DataService) { }
// to receive the data:
this.data.productsDataEmitter.subscribe(products=>{
console.log('the data array is', products);
});

//to update the data, use:
let newData: Array[Product] = [];
this.data.emitProductsData(newData);

If you wish to read and then update the same subscribed data, ensure that you perform it within 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);
});

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The specified '<<custom component name>>' argument does not match the 'Type<<custom component name>>' parameter

I'm currently facing an error that indicates a type parameters mismatch, but I can't pinpoint where in the process it's happening. Argument of type 'ModalUserInfoComponent' is not assignable to parameter of type 'Type<Mo ...

The updated values in an Angular application may not always be accurately represented by interpolated values

The values of the elements in the dropzone1 array only show the initial top and left values, not the latest ones. Within the draw() function, I add the top and left values to the topLeft array and then push it to the dropzone1 array inside the move() func ...

The directive for accepting only numbers is not functioning in versions of Chrome 49.xx.xx and earlier

I have implemented a directive in Angular 6 to allow only numbers as input for certain fields. The directive code is shown below: import { Directive, ElementRef, HostListener } from '@angular/core'; @Directive({ selector: '[NumbersOnly]& ...

Is the Prisma model not reachable through Prisma Client?

I'm currently attempting to retrieve a specific property of a Prisma model using Prisma Client. The model in question is related to restaurants and includes a reviews property that also corresponds with a separate Review model. schema.prisma file: // ...

Obtain PDF File using Typescript

I am attempting to use an AJAX Post to download a PDF file and return the templateFile Model. However, I am encountering an error where it cannot convert type TemplateFileDto to IhttpActionResult. Should I consider returning something different? Any assist ...

Observable in RxJS with a dynamic interval

Trying to figure out how to dynamically change the interval of an observable that is supposed to perform an action every X seconds has been quite challenging. It seems that Observables cannot be redefined once they are set, so simply trying to redefine the ...

Mastering Redux Toolkit - Ensuring Payload Type Verification is in Place when Invoking an Action Creator

I have been utilizing the redux toolkit for a while now and I appreciate how it helps in reducing redundant code. I am also interested in incorporating typescript, but I am facing challenges with getting the typechecking of an action payload to function pr ...

Interact with SOAP web service using an Angular application

I have experience consuming Restful services in my Angular applications, but recently a client provided me with a different type of web service at this URL: http://123.618.196.10/WCFTicket/Service1.svc?wsdl. Can I integrate this into an Angular app? I am ...

Top recommendations for implementing private/authentication routes in NextJS 13

When working with routes affected by a user's authentication status in NextJS 13, what is the most effective approach? I have two specific scenarios that I'm unsure about implementing: What is the best method for redirecting an unauthenticated ...

Node Sass was unable to locate a binding for the current environment you are using: OS X 64-bit running Node.js 12.x

Currently, I am encountering an issue while constructing an Angular project. The error message that I am facing is as follows: ERROR in Module build failed (from ./node_modules/sass-loader/lib/loader.js): Error: Missing binding /XXXXXXX/node_modules/nod ...

Looking for an Ionic 3 search function to filter a JSON array?

I am currently developing a market app using ionic 3, and one of the key features is the "products" list. Instead of manually inputting data, my "products page" retrieves items from a JSON array through an HTTP post request: postProducts(type){ return th ...

How can I combine multiple requests in RxJS, executing one request at a time in parallel, and receiving a single combined result?

For instance, assume I have 2 API services that return data in the form of Observables. function add(row) { let r = Math.ceil(Math.random() * 2000); let k = row + 1; return timer(r).pipe(mapTo(k)); } function multiple(row) { let r = Math.c ...

Error when running end-to-end tests in Angular CLI using the ng e2e

Recently, I created a new Angular 4 project using the Angular CLI. Upon running ng e2e, the sample end-to-end test worked flawlessly. However, when I later added a subfolder named services in the app folder and generated a service within it, the ng e2e com ...

Transforming a "singular or multiple" array into an array of arrays using TypeScript

What is causing the compilation error in the following code snippet, and how can it be resolved: function f(x: string[] | string[][]): string[][] { return Array.isArray(x[0]) ? x : [x]; } Upon inspection, it appears that the return value will constantly ...

Operating on Javascript Objects with Randomized Keys

Once I retrieve my data from firebase, the result is an object containing multiple child objects. myObj = { "J251525" : { "email" : "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="6c3823212 ...

Why is my terminal showing certain output when I execute the command npm start?

I have a burning question. Upon running npm start in angular2, what exactly am I witnessing on my terminal screen? Where is this information originating from? I'm referring to: [1] No detection of a `bs-config.json` or `bs-config.js` override file. D ...

Enhancement of Nebular Theme from version 4.4.0 to 9.0.1 in relation to Angular (from 8.2.3 to 13.2.1)

Upon upgrading from Nebular Theme version 4.4.0 to 9.0.1 and Angular version 8.2.3 to 13.2.1, I encountered the following issues: 'nb-card-header' is not recognized as a valid element: If 'nb-card-header' is an Angular component, ens ...

What is the best way to get my Discord bot to respond in "Embed" format using TypeScript?

I've been attempting to create a bot that responds with an embedded message when mentioned, but I'm running into some issues. Whenever I run this code snippet, it throws an error in my terminal and doesn't seem to do anything: client.on(&apo ...

Patience is key as you await the completion of an API call in Angular 14

Within my Angular 14 application, I am faced with a scenario where I need to make two API calls and then combine the results using "combineLatest" from rxjs. The combined data is then assigned to a variable that I must use in a separate function. How can I ...

Angular 7 flex layout ensures that the table fills its parent container completely without overstretching it

Hello, I'm encountering a problem with the sample found on StackBlitz. My goal is to confine the table to one page and have the remaining height filled after the header. If the table exceeds this height, I would prefer it to be hidden. However, based ...