Observables cannot include a finally block when transitioning from an error state

This isn't the first time I've come across this issue. I need to display data on a web page even if the http request fails, so I have some logic in the err state. To avoid duplicating code in both subscribe and err, I typically write it within the complete/finally state.

this.loadingResults = true;
this.service.get().subscribe(data => {
   // manipulate the retrieved data
}, err => {
   this.initializeData();
}, () => {
   this.loadingResults = false;
   this.cd.detectChanges(); 
});

Since I use a spinner on the page to indicate waiting for a response, I want to change the loadingResults value to false upon receiving the response (whether successful or not) and refresh the page using ChangeDetectorRef.

The issue arises when the aforementioned code doesn't function correctly, leading me to give up on the finally function:

this.loadingResults = true;
this.service.get().subscribe(data => {
   // do something with the data
   this.loadingResults = false;
   this.cd.detectChanges(); 
}, err => {
   this.initializeData();
   this.loadingResults = false; // repeating code
   this.cd.detectChanges(); // repeating code
});

What is the best approach to utilizing the finally function while preventing redundant code across different response scenarios? It appears that its behavior differs from backend try-catch-finally blocks (such as in Java or C#).

Answer №1

When it comes to the subscribe callbacks like error and complete, they cannot be triggered simultaneously. Utilizing the finalize operator is a great alternative. This operator will be activated in the event of completion or encountering errors.

this.loadingResults = true;
this.service.get().pipe(
  finalize(() => {
    this.loadingResults = false;
    this.cd.detectChanges(); 
  })
).subscribe(
  data => {
    // handle data
  }, 
  err => {
    this.initializeData();
  }
);

In addition, why are you manually triggering change detection? Is there a reason why it's not being automatically initiated?

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

Guide to integrating dexie with typescript and requirejs

My current project in Typescript involves using requirejs to load jQuery successfully. However, I'm encountering difficulties setting up Dexie. Here is how my require config is set up: require.config({ baseUrl: '', paths: { ...

Utilizing Angular 2 to Make Restful API Requests with Windows Authentication

I am currently facing an issue with my .net web api hosted on IIS 7, which uses windows authentication. My goal is to access this web api using Angular 2, TypeScript, and Node.js. Initially, I encountered an error stating 'Response to preflight reques ...

Inheritance of Type Member in TypeScript

My data structure looks like this: export abstract class Person { ... } export class FPerson extends Person { a: A; b: B; } export class JPerson extends Person { c: C; } export class User { person: Person; } When dealing with the s ...

Having trouble getting Sass extending to work in a basic scenario?

Here we have a simple example of Sass code, an Angular 2 component that accesses the Sass code, and the rendered HTML. However, there seems to be an issue with the blueBig span element in the last part. As someone new to Sass, I am not sure why this basic ...

Leverage the power of TypeScript with knockout's pureComputed function

I am facing an issue with referencing the this object in a function called problem: const c = { f() { console.log("hi"); }, problem: ko.pureComputed(() => { return this.f(); }), }; [ts] The containing arrow function captures the glob ...

Navigate through nested JSON structure without prior knowledge of specific layer names

Is it feasible to iterate through this complex nested object without prior knowledge of the varying views ("A", "B", "C", etc.) it contains? I currently rely on an alphabetic index, but I've been informed that the "view layer" might have diverse names ...

The 'then' property is not found on the type 'CloudFunction<Change<DocumentSnapshot>>'

Encountered an error: The property 'then' does not exist on type 'CloudFunction>' in my Firebase cloud function. Does anyone have a solution? exports.rebuildFormTriggerClientDetails = functions.firestore. document('clientDeta ...

What is the best way to pass the modal dialog parameter sent from HTML to the TypeScript page?

I have implemented a dialog window using Angular where it opens by passing a parameter in the HTML side along with a transaction. To further enhance the functionality of my page, I want to incorporate the fab button. However, I am facing a challenge in sen ...

What is the correct way to express an object in an array?

I've encountered an issue: I'm working with an array called _daysConfig<DayConfig> When I manually populate it like this, everything functions correctly: _daysConfig: DayConfig[] = [ { date: new Date('Wed Jul 22 2020 21:06:00 GMT+02 ...

Error message: "Incompatible types in Typescript"

As I delve into learning TypeScript, I have encountered two errors that are causing me some trouble. We have a problem with the following lines of code: Type 'string | null | undefined' is not assignable to type 'string | RegExp | QuerySelec ...

Ways to cycle through various selectors

I'm in the process of developing a form that allows users to assign properties to multiple files before importing them into my database. It's crucial for me to know the source and sport associated with each file before proceeding with the import. ...

Uploading images with Angular, Node.js, and MySQL

Is there a way to upload an image to a MySQL blob field using node.js, and then use Angular to display it as an image? I'm looking for suggestions on how to accomplish this. Any ideas? ...

How can I incorporate TypeScript paths into Storybook with Webpack version 5?

Storybook includes a pre-configured Webpack setup. Up until Webpack v4, it was possible to utilize tsconfig-paths-webpack-plugin and define custom tsconfig (or any other plugin) like so: const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plug ...

Error building Angular module occurred while executing the project

Recently, I got an Angular template from this site: After successfully running npm install, I encountered an error when trying to run ng serve: ./src/styles.scss - Error: Module build failed (from ./node_modules/mini-css-extract-plugin/dist/loader.js): Mo ...

The correct method for defining a multi-type model for a single property in TypeScript

I'm facing an issue where I need to save an object as a JSON string in the database, but keep encountering errors and warnings because the model is set as either a string or an object. Do I need two separate models for post and get requests? Or is the ...

Implement dynamic typing in the sort function to restrict it to only accept number properties

I need help creating a pipe that can sort an array of objects based on a specified property. While I have managed to make it work, I am encountering a type error in my code. Here is the snippet: export const sortByProperty = <T>(a: T, b: T, property: ...

What is the best way to organize the data retrieved from the api into a map?

In my search page component, I display the search results based on the user's query input. Here is the code snippet: "use client"; import { useSearchParams } from "next/navigation"; import useFetch from "../hooks/useFetch&qu ...

The latest update of Google Maps Javascript API Version 3.54 is causing compatibility issues with Angular Google Maps 13.2

Since Nov 16, 2023, a concerning issue with Google Maps has emerged in my Angular Application. The problem involves receiving 403 Errors from Google Maps and the maps failing to load (resulting in a blank page), despite having a valid API Key. The followi ...

Is it possible to reach my Node.js server within the container using localhost?

Currently, I am in the process of learning how to develop a website using Angular. In addition, we are also exploring Docker by containerizing our project. Our objective is to have Angular exclusively installed within the container, with our code located o ...

What is the best way to transfer information from a component to the routing module in Angular version 16?

Currently, I have been developing a Single Page Application (SPA) using Angular 16, TypeScript, and integrating The Movie Database (TMDB). One of the components I've built displays movies based on genre: import { Component } from '@angular/core& ...