"Can you guide me on how to invoke a parent function from retryWhen in Angular

I'm struggling to figure out how to execute a function from retryWhen and then call the parent function once retryWhen is done. Any ideas on how I can achieve this?

getStatuses(statusesType: string[]): Observable<IStatus[]> {

        let body = JSON.stringify({ "StatusesType": statusesType});
        let headers = new Headers({ 'Content-Type': 'application/json' });
        headers.append('Authorization', 'Bearer ' + localStorage.getItem("access_token");
        headers.append('Access-Control-Allow-Origin', '*');
        let options = new RequestOptions({ headers: headers });

        return this.http.post(this._baseUrl + '/statuses/statusesList', body, options)
            .retryWhen(error => this.refreshToken())
            .map((res: Response) => {
                this.statusesrecieved = res.json();
                return this.inspections;
            });
    }

I need to have getStatuses() function called again after executing refreshToken() in retryWhen. Any help would be greatly appreciated.

I also attempted using retry like this but it didn't work:

 return this.http.post(this._baseUrl + '/statuses/statusesList', body, options)
                .retryWhen(error => this.refreshToken())
                .map((res: Response) => {
                    this.statusesrecieved = res.json();
                    return this.inspections;
                }).retry(5);
        }

Below is my refreshToken function

refreshToken(): Observable<any> {
        console.log("refreshing token");

        let body: string = 'grant_type=refresh_token&refresh_token=' + localStorage.getItem("refresh_token");
        let headers = new Headers();
        headers.append('Content-Type', 'application/x-www-form-urlencoded');
        let options = new RequestOptions({ headers: headers });


        return Observable.create(
            (observer: Observer<any>) => {
                this.http.post('https://fedqa.test.com/as/token.oauth2', body, options)
                    .map(res => res.json()).subscribe(
                    (data) => {

                        localStorage.removeItem("access_token");
                        localStorage.removeItem("refresh_token");
                        localStorage.setItem("access_token", data.access_token);
                        localStorage.setItem("refresh_token", data.refresh_token);
                        localStorage.setItem("token_type", data.token_type);
                        localStorage.setItem("expires_in", data.expires_in);
                    },
                    (error) => {

                        Observable.throw(error);
                    }
                    );
            });
    }

Answer №1

My assumption is that:

  1. I assume that this.refreshToken() is asynchronous and returns an Observable that finishes once it's done.
  2. this.refreshToken() updates as a side effect and will be updated after the Observable completes.

You can utilize concat which subscribes to an observable after the previous one completes(!!).

getStatuses() immediately retrieves the token from local storage so it cannot be directly used in concat, it needs to trigger after this.refreshToken is finished; consider using Observable.defer:

...
.retryWhen(
  errors => this.refreshToken()
    .concat(Observable.defer(() => getStatuses(statusesType)))
)

While this approach could be effective, there is a possibility of infinite recursion occurring. You may also want to explore retry which allows specifying the maximum number of retries before emitting an error.

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

Ensuring Type Compatibility Between Classes and Object Literals in TypeScript

When working with TypeScript, it is important to note that an object literal can be assigned to a class typed variable as long as the object provides all properties and methods required by the class. class MyClass { a: number; b: string; } // The co ...

What is the best way to launch an event when a component is accessed through navigation?

I am working on an angular2 application (RC5) that includes a chapter component containing a large template file named chapter.html. The template features different sections for each chapter specified by conditionals like: <div *ngIf="chapter == 1"> ...

Utilizing a Bootstrap Collapse component based on scrolling actions

I'm currently working on an Angular application that incorporates Bootstrap 5.2. Within this project, I have successfully implemented the Collapse component on a card, utilizing data attributes. However, my goal is to trigger the collapse of the card ...

The distinctUntilChanged function encounters an issue when no comparison function is given

considering the following code: /** * Generating a stream of car objects from an array. */ from([ { name: 'Porsche', model: '911' }, { name: 'Porsche', model: '911' }, { name: 'Ferrari', model: &apo ...

Updating the status of various sections with Redux toolkit

Is it possible to update the state of a store, which consists of multiple slices, with a new state in React using Redux Toolkit? While you can revert the entire store to its initial state using extraReducers, is it also possible to change the state to som ...

Compiling TypeScript files from multiple source directories

Having 3 NodeJs applications with the latest versions of Typescript code, each containing an "src" folder with TypeScript code files and a "dist" folder with JavaScript files compiled by Typescript. I am now looking to create a "common" folder outside of ...

Can you please explain the distinction between the .ts and .tsx file extensions? They are both commonly used for TypeScript files in a React environment, but what is the specific use case for each

Hello, I'm in the process of learning React and as I work on my project, I've noticed files with both the .ts and .tsx extensions. I'm a bit confused about when to use .ts versus .tsx. Any guidance on this topic would be greatly appreciated. ...

Overlap occurs when Angular Material 2 cards are used in conjunction with flex-layout

I'm currently working on implementing Angular Material 2 cards with flex-layout to dynamically change the number of columns displayed as the browser is resized. My goal is to achieve a layout similar to how Google Keep works. <div *ngIf="condition ...

Ways to extract X-Total-Count from json-server using Angular's http.get function

Currently, I am utilizing json-server on localhost:3000. The setup is running smoothly, and I can fetch data in Angular through http.get. My objective is to access the response header X-Total-Count within the Angular .subscribe method. However, I am unab ...

Each page in NextJS has a nearly identical JavaScript bundle size

After using NextJS for a considerable amount of time, I finally decided to take a closer look at the build folder and the console output when the build process is successful. To my surprise, I noticed something peculiar during one of these inspections. In ...

Module logo.svg not found? Error in Typescript

Integrating package: vue-svg-loader. Established the file svg.d.ts with the content below: declare module '*.svg' { const content: any export default content } Utilizing it in a component in the following manner: import register from &apo ...

promise not being returned by service method

In my Angular 8 application, I am facing an issue where the promise call does not return an exception when it occurs. Can someone help me understand how to make getRepApprovedName return a promise? When I use 'return http.get', I encounter a synt ...

Generate div elements with a row capacity of 3 and a column size of N

I am trying to arrange divs in a way that they can be scrolled horizontally. I have set up a flex container, but I'm unsure what other steps are needed to ensure the boxes align to the left. You can view the demo code here .container { height: 95px ...

Tips for adding an item to an array within a Map using functional programming in TypeScript/JavaScript

As I embark on my transition from object-oriented programming to functional programming in TypeScript, I am encountering challenges. I am trying to convert imperative TypeScript code into a more functional style, but I'm struggling with the following ...

Leveraging the power of Angular's function within ElementRef and accessing the

Is there a way to access an Angular function using ElementRef? ngAfterViewInit() { let _self = this; this.datatable.on('m-datatable--on-layout-updated', function(e){ $(_self.elRef.nativeElement).find('.deleteFn').c ...

"Combining the power of AngularJS2 beta with Spring Boot: the ultimate

I am currently using Atom 1.4.0 with the atom-typescript package to develop AngularJS2 modules in TypeScript. On the backend, I have a spring-boot application for handling the REST APIs. After making changes to the .ts files in Atom, it seems to compile t ...

Parent composition failing to receive emissions from Vue3 child component

Recently started learning vue and exploring event handling between Children and Parents. I've developed a child component with an emit exposed in the script setup: const emit = defineEmits(['OnTileClicked']) function TileClicked() { ...

Tips for creating the perfect ngrx state structure

Currently, I am working on adding a new feature state that includes a graph state with two subfeatures: node state and link state. Here is how I have implemented the graph state and reducer: export interface GraphState { [fromNode.featureKey]: fromNode ...

Using formArray to dynamically populate data in Angular

I am attempting to showcase the values from a formarray that were previously added. component.ts this.companyForm = this.fb.group({ id: [], company_details: this.fb.group({ ---- }), company_ip_addresses: this.fb.array([this.fb.group({ ...

performing resolver when needed in angular version 5

I have been working on a project using Angular and recently updated it from version 4.2 to Angular 5. Although I haven't utilized any new features introduced in Angular 5 yet. My current task involves executing a resolver on a specific route when a c ...