Angular 8 HTTP Interceptor causing issues with subscriptions

I'm currently in the process of setting up an Angular 8 project that will allow me to mock API calls using HTTP INTERCEPTORS. My approach involves adding a --configuration=mock flag to my ng serve script so that the interceptor is injected into my app.module, resulting in data being fetched from a JSON file instead of an external API. I found inspiration from this example: https://stackblitz.com/edit/angular-mock-http-interceptor For some reason, after implementing the interceptor, the subscription between my component and the data service seems to be broken. Despite building the same array structure for both the live and mock services, I cannot pinpoint why it's causing an issue. Here are the getter method and Observable from the service:

getUsers() {
    this.http.get<any>('https://jsonplaceholder.typicode.com/users')
    .subscribe(fetchedUsers => {
      this.users = fetchedUsers;
      this.usersUpdated.next([...this.users]);
    });
  }

  getUsersUpdatedListener() {
    return this.usersUpdated.asObservable();
  }

The component that interacts with the service:

ngOnInit() {
    this.usersService.getUsers();
    this.usersSub = this.usersService.getUsersUpdatedListener()
    .subscribe((users: User[]) => {
      this.users = users;
    });
  }

And here is the code snippet for the interceptor class:

import { Injectable, Injector } from '@angular/core';
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse } from '@angular/common/http';
import { Observable, of } from 'rxjs';
import * as users from '../../assets/mockData/users.json';

const urls = [
  {
      url: 'https://jsonplaceholder.typicode.com/users',
      json: users
  }
];

@Injectable()
export class HttpMockRequestInterceptor implements HttpInterceptor {
    constructor(private injector: Injector) {}

    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        for (const element of urls) {
            if (request.url === element.url) {
                console.log('Loaded from json : ' + request.url);
                return of(new HttpResponse({ status: 200, body: ((element.json) as any).default }));
            }
        }
        console.log('Loaded from http call :' + request.url);
        return next.handle(request);
    }
}

You can access the entire project on GitHub: https://github.com/reynoldsblair/learn-http

Could you help me understand why the interceptor is causing issues within my project?

Answer №1

Hey there, just wanted to let you know that your interceptor is working perfectly fine. The issue lies in your user-list.component.ts file. It seems that the subscription to

this.usersService.getUsersUpdatedListener()
is happening after this.usersService.getUsers();, which can lead to a race condition. To fix this, make sure to move the subscription logic above the call to getUsers. Once you do that, everything should work smoothly for both HttpRequestInterceptor and HttpMockRequestInterceptor.

 ngOnInit() {
    this.usersSub = this.usersService.getUsersUpdatedListener()
      .subscribe((users: User[]) => {
        this.users = users;
      });
    this.usersService.getUsers();
  }

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

Refresh PrimeNG dataTable without reloading the table

Currently, I am implementing the functionality of adding new rows to a dataTable in my template. Here is the code snippet from the component: rows: any = {} newrow: any = {} addNewRow(key: string) { let rows = {...this.rows} let newrow = {_key: Math ...

Guide to uploading files in Vue.js v3

I'm trying to implement file upload functionality using Vue.js version 3. Although I have successfully imported ref, I am unsure how to utilize it for retrieving file data? FileUploadTest.vue <template> <h1>File Upload</h1> <div ...

Typescript | The extension of formikProps on IProps in Typescript is lacking 27 Props

I'm currently working with Formik in TypeScript and I'm trying to integrate a simple form component into TS within another component where I extract the defaultValues and validationSchemas. The challenge lies in accessing only the necessary form ...

The storage does not reflect updates when using redux-persist with next-redux-wrapper in a Typescript project

I'm currently working on integrating redux-persist with next.js using next-redux-wrapper. However, I'm facing an issue where the storage is not updating and the state is lost during page refresh. Below is my store.ts file: import { createStore, ...

Upload button allowing multiple values to be uploaded as a single file

I'm currently facing an issue with my list of values and upload buttons. The file upload functionality is working correctly, but the problem arises when I try to upload a file for any item in the list - it always uploads for the first item only. Here ...

Craft a specialized script for manipulating the DOM

I'm currently working on a project using Angular 2. I have implemented a menu that should be able to close when a button is clicked. Instead of using a component for the menu, I want to keep it lightweight by placing it outside of Angular. However, I ...

Exploring the potential of utilizing arguments within the RxJS/map operator

When working with rxjs, export function map<T, R, A>(project: (this: A, value: T, index: number) => R, thisArg: A): OperatorFunction<T, R>; I seem to be struggling to find a practical use for thisArg: A. ...

Using Material UI Slider along with Typescript for handling onChange event with either a single number or an

Just diving into Typescript and encountered an issue with a Material UI Slider. I'm trying to update my age state variable, but running into a Typescript error due to the typing of age being number and onChange value being number | number[]. How can I ...

Suggestions for autofilling in Angular 8 on the password field

Despite multiple discussions on stackoverflow, a solution to disabling browser AUTO-FILL suggestions on fields still eludes me. Does anyone know of a reliable method to prevent these pop-ups from appearing? <mat-form-field> <input ...

The 'id' property is not found within the 'Order[]' type

Encountering a perplexing issue in my HTML where it keeps showing an error claiming that the 'id' property does not exist on type Order[] despite its clear existence The error message displayed: Property 'id' does not exist on type &ap ...

The Angular 2 project, built with the CLI tool, has been transformed into an npm

We have a project in the works that involves creating a large application using angular 2. This project consists of one main parent angular 2 application and three separate sub-child applications that are unrelated to each other. Each of these sub-child ...

Deactivate the button in the final <td> of a table generated using a loop

I have three different components [Button, AppTable, Contact]. The button component is called with a v-for loop to iterate through other items. I am trying to disable the button within the last item when there is only one generated. Below is the code for ...

Guarding against Angular routes that do not have a component and may include an

Currently, I am in the process of locking down routes by making an API call to check permissions. The existing routes are as follows: { path: '', children: [ { path: '', component: HomeComponent}, { path: ' ...

After saving any HTML, SCSS, or TS file, Angular 12 does not compile immediately

Recently I upgraded my Angular project from version 8 to 12 and then migrated to eslint. However, I have encountered an issue where the compilation does not begin immediately after saving a file. There is a delay of approximately 2 minutes before the compi ...

When working with TypeScript, how do you determine the appropriate usage between "let" and "const"?

For TypeScript, under what circumstances would you choose to use "let" versus "const"? ...

Typescript type/object's conditional property feature

Imagine having a recipe ingredient type structured like this export type RecipeIngredient = { name: string; amount: Number | string; unit: "grams" | "milliliters" | "custom"; }; To illustrate const apples: RecipeIngredient = { name: 'apples&a ...

Unable to send event from JavaScript to Component in Ionic

My goal is to notify a component that a script file has finished loading. My approach involves using the onload event of an element to dispatch an event. A service will then register an event listener for this event, waiting for clients to subscribe to an ...

Tips on extracting value from a pending promise in a mongoose model when using model.findOne()

I am facing an issue: I am unable to resolve a promise when needed. The queries are executed correctly with this code snippet. I am using NestJs for this project and need it to return a user object. Here is what I have tried so far: private async findUserB ...

The navigation bar is struggling to be positioned on top of the body

I have encountered an issue where I want my navbar to remain on top of all components, but when I open the navigation menu, it pushes all the components of the index page down. My tech stack includes Next.js, Tailwind CSS, and Framer Motion. This problem ...

Altering the properties of a specified element within TestBed using the overrideComponent method

We are implementing TestBed.overrideComponent() to substitute a component with custom behavior. TestBed.overrideComponent(CoolComponent, { set: { template: '<div id="fake-component">i am the fake component</div>', sel ...