0
votes

Hi I have an angular application where I'm passing data from one component to a service and trying to update the value of a behavior subject in that service by calling it's next function so it in turn updates a subscribe value in another component. My issue is when passing the data and creating an object to pass to the behavior subject the next function doesn't execute. Here is the code.

My ShopService.ts

I've left out other functions in the code for sake of space but they should have no bearing on the code i'm trying to implement

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

import { AuthService } from 'src/app/auth/auth.service';
import { Product } from '../models/product.model';

import { BehaviorSubject } from 'rxjs';
import { take, exhaustMap, tap } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})
export class ShopService {

  productsSubject = new BehaviorSubject<Product[]>(null);

  productSubject = new BehaviorSubject<Product>(null);

  productObs = this.productSubject.asObservable();

  private products: Product[];

  private product: Product;

  private userToken;

  constructor(private http: HttpClient, private authService: AuthService) {

  }

 // trying to update the behavior subject here but next never executes but data is logged to console
 editProductForm(id: string, title: string, price: number, imagePath: string, description: string) {
     this.product = new Product(title, price, imagePath, description, id);
     console.log('edit product ' + this.product.title);
     this.productSubject.next(this.product);
  }
}

admin-shop.component.ts

This is where i'm trying to subscribe to the behavior subjects value once it's updated

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

import { ShopService } from '../services/shop.service';

import { Subscription } from 'rxjs';

import { Product } from '../models/product.model';

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

  @Output() editProductEvent = new EventEmitter<boolean>();

  productSub: Subscription;

  product: Product;

  error: string;

  isLoading = false;

  isEditing = false;

  constructor(private shopService: ShopService) { }

  ngOnInit() {
    this.productSub = this.shopService.productSubject.subscribe(product => {
      if (product) {
        console.log('editing product' + product);
        this.editProductEvent.emit(true);
        this.product = new Product(
          product.title,
          product.price,
          product.imagePath,
          product.description,
          product._id);
      }
    });
  }
}

item-list.component.ts

This is where i'm sending the data to the service and I know it's being sent as it's being logged in the console once it reaches the service.

import { Component, OnInit, OnDestroy } from '@angular/core';
import { Product } from '../models/product.model';
import { ShopService } from '../services/shop.service';
import { Subscription } from 'rxjs';

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

  products: Product[] = [];

  private shopSub: Subscription;

  private subjectSub: Subscription;

  constructor(private shopService: ShopService) { }

  editProduct(id: string, title: string, price: number, imagePath: string, description: string) {
    this.shopService.editProductForm(id, title, price, imagePath, description);
  }
}

The code I've supplied is where the issue lies because I've already behavior subjects in other parts of my application that work as intended it's just when I send the data from the item-list component to the service it logs the data but doesn't update the behavior subject and it never reaches the subscription as no data is then logged in the admin-shop components subscription code.

Hopefully I've supplied enough to find the answer but if not please ask for anything more you may deem necessary. Thanks in advance :)

Here's the app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { FormsModule } from '@angular/forms';

import { AppComponent } from './app.component';
import { HeaderComponent } from './header/header.component';
import { HomeComponent } from './home/home.component';
import { AuthComponent } from './auth/auth.component';
import { DropDownDirective } from './util/dropdown.directive';
import { HttpClientModule } from '@angular/common/http';
import { LoadingSpinner } from './util/loading-spinner/loading-spinner.component';
import { AdminComponent } from './admin/admin.component';
import { DashboardComponent } from './admin/dashboard/dashboard.component';
import { AdminShopComponent } from './admin/dashboard/admin-shop/admin-shop.component';
import { AdminProfileComponent } from './admin/dashboard/admin-profile/admin-profile.component';
import { ItemListComponent } from './admin/dashboard/item-list/item-list.component';
import { BlockchainComponent } from './blockchain/blockchain.component';


@NgModule({
  declarations: [
    AppComponent,
    HeaderComponent,
    HomeComponent,
    AuthComponent,
    DropDownDirective,
    LoadingSpinner,
    AdminComponent,
    DashboardComponent,
    AdminShopComponent,
    AdminProfileComponent,
    ItemListComponent,
    BlockchainComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    FormsModule,
    HttpClientModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

3
You probably have two different instances of the service. Add a constructor to t, containing a colnsole.log() statement. Check how many times you get that statement. - JB Nizet
Do u provides ur services in providers section in any module ? - TintinSansYeux
I agree with @JB Nizet, can you post your app.module - Alberto Lerdo
No all services are defined as @Injectable({ providedIn: root }). Yea i'll post my app.module.ts in a moment. Thanks everyone - A.Healy
Posted app.module.ts there - A.Healy

3 Answers

1
votes

Looks like your service is not being instantiated. Try importing your service into app.module under Providers

Import { ShopService } from '../services/shop.service';// Or wherever it's at
...
  providers: [ShopService],

0
votes

you are instantiating the event emitter inside the same component that is setting it to true. so it's letting itself know that it has been edited but no one else. since you're using a service, you can just update a variable there when it gets changed and subscribe to that change in your component. good luck!

0
votes

my import file for the service is different in both the component- In one component I am using services/SeekerJobService.js and on other services/SeekerJobService

That why the object on subscribing is null.