multiple angular 17 http get request not happening in the network

After upgrade to angular 17 the HttpClient looks to cache http GETs and just runs it once.

multiple calls to the api

I expected to see more requests in the network but actually it just shows up the first request. All subscribes to the httpClient Observable shows the same first result.

my app.config

export const appConfig: ApplicationConfig = {
  providers: [
    provideRouter(
      routes,
      // withPreloading(PreloadAllModules),
      // withDebugTracing(),
      withComponentInputBinding(),
      withRouterConfig({
        paramsInheritanceStrategy: 'always',
      })
    ),
    importProvidersFrom(
      BrowserModule,
      LightboxModule,
      OverlayModule,
      SocketIoModule.forRoot(config),
      MatDialogModule,
      MatSnackBarModule,
      provideFirebaseApp(() => initializeApp(environment.firebaseConfig)),
      provideAuth(() => getAuth()),
      TranslateModule.forRoot({
        loader: {
          provide: TranslateLoader,
          useFactory: HttpLoaderFactory,
          deps: [HttpClient],
        },
      })
    ),
    { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true },
    provideAnimations(),
    provideHttpClient(withInterceptorsFromDi(), withFetch()), // withInterceptors([relativePathInterceptor])
    provideStore(),
    provideEffects(),
    isDevMode() ? provideStoreDevtools() : [],
    provideClientHydration(),
  ],
};

this is my angular.json

{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "version": 1,
  "newProjectRoot": "projects",
  "projects": {
    "sugar": {
      "projectType": "application",
      "schematics": {
        "@schematics/angular:component": {
          "style": "scss"
        }
      },
      "root": "",
      "sourceRoot": "src",
      "prefix": "app",
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:application",
          "options": {
            "outputPath": "dist/sugar",
            "index": "src/index.html",
            "browser": "src/main.ts",
            "polyfills": ["zone.js"],
            "tsConfig": "tsconfig.app.json",
            "inlineStyleLanguage": "scss",
            "assets": ["src/favicon.ico", "src/assets"],
            "styles": ["src/styles/styles.scss"],
            "scripts": [],
            "server": "src/main.server.ts",
            "prerender": true,
            "ssr": {
              "entry": "server.ts"
            }
          },
          "configurations": {
            "production": {
              "budgets": [
                {
                  "type": "initial",
                  "maximumWarning": "500kb",
                  "maximumError": "1mb"
                },
                {
                  "type": "anyComponentStyle",
                  "maximumWarning": "2kb",
                  "maximumError": "4kb"
                }
              ],
              "outputHashing": "all"
            },
            "development2": {
              "optimization": false,
              "extractLicenses": false,
              "sourceMap": true
            }
          },
          "defaultConfiguration": "production"
        },
        "serve": {
          "builder": "@angular-devkit/build-angular:dev-server",
          "configurations": {
            "production": {
              "buildTarget": "sugar:build:production"
            },
            "development": {
              "buildTarget": "sugar:build:development2"
            }
          },
          "defaultConfiguration": "development"
        },
        "extract-i18n": {
          "builder": "@angular-devkit/build-angular:extract-i18n",
          "options": {
            "buildTarget": "sugar:build"
          }
        },
        "test": {
          "builder": "@angular-devkit/build-angular:karma",
          "options": {
            "polyfills": ["zone.js", "zone.js/testing"],
            "tsConfig": "tsconfig.spec.json",
            "inlineStyleLanguage": "scss",
            "assets": ["src/favicon.ico", "src/assets"],
            "styles": ["src/styles/styles.scss"],
            "scripts": []
          }
        }
      }
    }
  },
  "cli": {
    "analytics": "2d1ee5f9-3a66-4408-b599-05e081007ab2"
  }
}

my chat.service.ts

import { HttpClient, HttpParams } from '@angular/common/http';
import { Injectable, } from '@angular/core';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { Conversation } from './interfaces/user.interface';
import { environment } from '../../../environments/environment';

@Injectable({
  providedIn: 'root',
})
export class ChatService {
  withCredentials = environment.withCredentials;

  constructor(private http: HttpClient) {}

  getInbox(): Observable<Array<Conversation>> {
    // const url = `${environment.baseUrl}/api/chat/inbox?t=` + Date.now();
    const url = `${environment.baseUrl}/api/chat/inbox`;

    return this.http.get<Array<Conversation>>(url, {
      withCredentials: this.withCredentials,
      transferCache: false,
    });
  }
}

Upvotes: 0

Views: 486

Answers (1)

Fausto
Fausto

Reputation: 181

2 possible solutions

  1. instead of using simple http.get().pipe() or http.get().subscribe() use combineLatest, maybe also forkJoin on the "second" http.get(), wherever it fires! Something like: combineLatest([this.http.get()]).subscribe(response => {...});

  2. Workaround that you maybe already noticed: put a useless optional request parameter in the request url, whose value must change for every single request, like the comment you have:

    // const url = ${environment.baseUrl}/api/chat/inbox?t= + Date.now();

Just for completeness, I already tried many other possibilities but none of the following worked:

  • shareReplay in every request
  • manually unsubscribing (unsubscribe, finalize)
  • changing ChangeDetectionStrategy

Upvotes: 0

Related Questions