Changing from one subscription to another within the ngOnInit() function

I am facing an interesting challenge with my webpage. I have a grid where I display invoices, and there is an option to view payments related to each invoice. Clicking on a button takes the user to the payments page, where only the payments corresponding to that invoice are filtered and displayed. Additionally, when the user navigates to the payments tab in the navbar, all payments are shown in a grid. I have successfully implemented both functionalities in the ngOnInit() method, but now I need to be able to switch between the two seamlessly. I want to filter payments when the user clicks the button on the invoices page and show all payments when the user clicks on the payments tab in the navbar. I have experimented with different variables, equality checks in the if statement, and changing the location of the if statement, but so far, I have not been able to achieve the desired outcome.

If anyone has any suggestions or advice on how to efficiently switch between the two subscriptions to make this work, I would greatly appreciate the help.

ngOnInit() {
  this.sub = this.route.params.subscribe(
    params => {
      if (params == null) { //HERE LIES THE ISSUE
         this.invoiceNum = params['invoiceNum'];

         //displays FILTERED payments
        this.paymentService.showPayments(this.invoiceNum).subscribe(
        res => {
          this.payments = res.value;
          this.loading = false;
          console.log(res);
        },  
        err => {
          if (err.status == 401) {
            this.auth.logOut();
          }
          this.loading = false;
          console.log(err);
        }
      );
    } else {

      //displays ALL payments
      this.paymentService.getPayments().subscribe(
        res => {
          this.payments = res.value;
          this.loading = false;
          console.log(res);
        },
        err => {
          if (err.status == 401) {
            this.auth.logOut();
          }
          this.loading = false;
          console.log(err);
        }
      );
    }
   }
 );
}

Answer №1

If you need to handle different conditions, consider using the switchMap operator. This operator allows you to switch between different subjects based on a condition.

In this solution, the switchMap operator is used to switch from a Route Parameter Changes subject to an HTTP Request for payments subject. If the router params include an invoiceNum, it will return a subject for specific payments related to that invoice number. Otherwise, it will return a subject for all payments.

You can streamline your code by reusing your onNext/onError callbacks for both cases.

ngOnInit() {
  this.sub = this.route.params
  .pipe(
    switchMap(params => {
      if (params['invoiceNum'] !== undefined) {
        // Display filtered payments
        return this.paymentService.showPayments(this.invoiceNum);
      } else {
        // Display all payments
        this.paymentService.getPayments();
      }
    })
  )
  // Reuse onNext/onError callbacks
  .subscribe(
    res => {
      this.payments = res.value;
      this.loading = false;
      console.log(res);
    },  
    err => {
      if (err.status == 401) {
        this.auth.logOut();
      }
      this.loading = false;
      console.log(err);
    }
  );
}

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

Tips for managing your time while anticipating an observable that may or may not

I am facing a dilemma in my Angular app where I need to conditionally make an HTTP call to check for the existence of a user. Depending on the result of this call, I may need to either proceed with another API request or halt the processing altogether. I ...

When you compile TypeScript with the target set to 'ES3' or 'ES5', it creates an internal structure

Recently delved into the world of TypeScript and experimenting with webpack ts-loader and babel-loader to compile and transpile TypeScript into ES5. However, I came across a compiler option in tsc that can target 'ES5', which made me question the ...

Create categories for static array to enable automatic suggestions

I have a JavaScript library that needs to export various constants for users who are working with vscode or TypeScript. The goal is to enable auto-complete functionality for specific constant options. So far, I've attempted to export a Constant in th ...

Passing optional inputs in Angular using ngx-charts is a simple and convenient

Currently delving into Angular 8 and ngx-charts. My goal is to showcase graphs sourced from configuration files. To achieve this, I have enabled the configuration file to offer multiple graphic options (essentially encompassing most options available at ) ...

ESLint is unable to locate the OnInit function within the "@angular/core" module

There seems to be an error: import { Component, OnInit, Input, ViewChild, ElementRef } from "@angular/core"; OnInit not found in '@angular/core'eslintimport/named The code appears to be functioning correctly, so perhaps there is a m ...

What is the method for extending props from React.HTMLProps<HTMLButtonElement>?

"react": "^17.0.2", "typescript": "^4.2.4" Can someone help me understand how to extend props from React.HTMLProps? import { FC, HTMLProps } from 'react' export interface SliderButtonProps extends HTMLPro ...

the category is unspecified

As I try to deploy my code and run the build, TypeScript is throwing an error stating that 'object' is of type unknown. I am currently working on resolving this issue in my specific scenario. export default function Home() { async function send ...

obtaining the value of an input using typescript (put request)

Does anyone know how to extract input values and store them as JSON? I'm having trouble with accessing the input value in this scenario. When I attempt document.querySelector("todo-text").value, it results in an error. const NewTodo: React.FC<NewT ...

Encountering a TypeError while working with Next.js 14 and MongoDB: The error "res.status is not a function"

Currently working on a Next.js project that involves MongoDB integration. I am using the app router to test API calls with the code below, and surprisingly, I am receiving a response from the database. import { NextApiRequest, NextApiResponse, NextApiHandl ...

Get rid of the filter arrows in the top row of a styled SpreadJS spreadsheet

Exploring SpreadJS for the first time has been an interesting journey as I dive into understanding table styling. While trying to apply styles across the entire table, I noticed a peculiar issue that arises. Upon applying a theme, whether it be custom or ...

Serving sourcemaps for a web extension in Firefox: A step-by-step guide

Currently in the process of developing a web extension using TypeScript, I have encountered an issue with sourcemaps not loading properly. The use of parcel to bundle my extension has made the bundling process simple and straightforward. However, while the ...

Getting node siblings within an Angular Material nested tree: A comprehensive guide

Struggling to retrieve the list of sibling nodes for a specific Angular Material tree node within a nested tree structure. After exploring the Angular Material official documentation, particularly experimenting with the "Tree with nested nodes," I found t ...

The Vue CLI project, using Typescript, is facing challenges with building and running Mocha tests

My Vue 2 project, created using Vue CLi, is encountering numerous errors. While it compiles fine for development purposes, running unit tests or building for production results in a cascade of issues. Displayed below are some sample errors, along with sni ...

Troubleshooting Primevue Data table styling issues in Vue3

Currently, I am attempting to incorporate grids into my data table using primevue library. However, despite following the provided example at https://www.primefaces.org/primevue/datatable/dynamiccolumns, the gridlines are not appearing on the table. The c ...

Retrieve an item from the Ionic Firebase database

My current challenge is retrieving data from the Firebase database. user-service.ts getProfile(){ try {; return this.afDatabse.object(`profile/${this.afAuth.auth.currentUser.uid}`); } catch (e) { console.log(e); } } c ...

Display a variety of components in a single route

I have a question: Is it possible to show multiple components in one route in Angular 7? For example, if the route is '/' then I want to display HeaderComponent and SideBarComponent. So when the path is '/home', these two components alo ...

Tips for moving all elements from array2 to array1

I need assistance with a code snippet that involves pushing objects from array2 into array1. array1 = [{name:'first'}, {name:'second'}]; array2 = [{name:'third'}, {name:'fourth'}, {name:'five'}]; // Desir ...

What is the process for creating a method within a class?

Here is the current structure of my class: export class Patient { constructor(public id: number, public name: string, public location: string, public bedId: number, public severity: string, public trajectory: number, public vitalSigns: ...

Tips for modifying the UserRepresentation in keycloak REST API response

Whenever we send a GET request to the following URL: https://my-keycloak/admin/realms/test-realm/users We receive a comprehensive list of users who are associated with the test-realm. According to the Keycloak REST API documentation, this kind of respons ...

Expanding Classes through Index signatories

My attempt at creating an abstract class is not going as smoothly as I hoped. I suspect my limited knowledge of TypeScript is the primary issue, even though this seems like a common scenario. The abstract class I'm working on is called Program. It co ...