Ensure that Angular resolver holds off until all images are loaded

Is there a way to make the resolver wait for images from the API before displaying the page in Angular? Currently, it displays the page first and then attempts to retrieve the post images.

@Injectable()
export class DataResolverService implements Resolve<any> {
  constructor(
    private router: Router,
    private API: ApiService
  ) {}

  resolve(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<any> | Observable<never> {
    return this.API.getPostById(route.params.id).pipe(
      map(response => {
        if (response["images"]) {
          const images = [];
          response["images"].forEach(image => {
            this.API.getImageById(image.id).subscribe(
              (img: any) => {
                const imageObject = {
                  url: window.URL.createObjectURL(img),
                };
                images.push(imageObject);
              }
            );
          });
          response["images"] = images;
          return response;
        }

        return response;
      })
    );
  }
}

Answer №1

Give this a try:

@Injectable()
export class DataResolverService implements Resolve<any> {
  constructor(
    private router: Router,
    private API: ApiService
  ) {}

  resolve(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<any> | Observable<never> {
    return this.API.getPostById(route.params.id).pipe(
      switchMap(response => { // Try using switchMap here instead
        if (response["images"]) {
          return combineLatest(
            // Combine all image requests
            ...response["images"].map(image => this.API.getImageById(image.id)),
          ).pipe(
            map(images => images.map(image => ({ url: window.URL.createObjectURL(image) })),
            map(images => ({ response: images })), // This map might be unnecessary
          );
        } else {
         return of([]);
        }
      })
    );
  }
}

This should help you get started. The problem with your current approach is that you're subscribing to the inner observable and it may not be properly awaited by the route resolver.

Answer №2

Ensure that you are not returning "response" prematurely before the asynchronous method "this.API.getImageById(image.id)" has resolved. It is important to wait for all asynchronous iterations to complete before returning any data. There are several ways to achieve this, here is one approach:

return this.API.getPostById(route.params.id).pipe(
      map(async response => {
        if (response["images"]) {
          const images = [];
          response["images"].forEach(async image => {
           await this.API.getImageById(image.id).then(
              (img: any) => {
                const imageObject = {
                  url: window.URL.createObjectURL(img),
                };
                images.push(imageObject);
              }
            );
          });
          response["images"] = images;
          return response;
        }

        return response;
      })
    );

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

How to convert form fields into JSON format using Angular 2

Currently, I am in the process of learning angular2 and have encountered a roadblock. I have created a form where the values are populated through JSON. The form consists of both pre-filled fields and text input fields where users can enter data and select ...

Bypass the Array.reduce method in JavaScript

I'm currently working on finding an elegant solution to a toy example pattern. The goal is to stop the reduce algorithm immediately and return 0 when an element with a value of 0 is encountered, without processing the rest of the elements. let factor ...

Setting up jsonServer in gulp with typescript: A guide

Previously, I had set up a json server and used the following code to start it: I found guidance in this GitHub repository. Starting angular2 project with gulp gulp-live-server.js var gulpCore = require('gulp'); var gulpParam = require('g ...

Displaying images in Ionic from a JSON URL source

I am having trouble getting an image from a JSON to display on an Ionic card. Although I can see the JSON response in the console log, the image is not showing up on the card, leaving it blank. It seems like I'm making a mistake in the HTML code. Any ...

What is the best way to display "No results found" in Mat-select-autocomplete?

I am working with the mat-select-autocomplete for a multiselect dropdown. When searching for values that are not in the list, I want to display a message saying "No results found". Can someone please help me achieve this? Link to Code ...

The conversion of a newline in an Angular page is done using &lt;br/&gt tag

Here is a function I have: setLocalVariableOnAccepted(ogp, hb, responseJson) { if (responseJson.ofgp === undefined) { this.ogpStatus = 'orange'; this.ogpStatusMsg = responseJson.ofgp + ', <br/> No change. Previous va ...

Dealing with Angular.js $http intercept error "net::ERR_CONNECTION_REFUSED"

Currently, I am attempting to create a universal error handler for my website utilizing $http interceptors. However, it seems that the interceptors are not functioning as intended. I have set up interceptors for 'response' and 'responseErro ...

How can I retrieve the OptionID value upon click?

How can I retrieve the value of OptionID when the Add button (.plus-link) is clicked? Each list item may contain a dropdown select menu or not. <ul> <li> <div class="menux"> <div class="text-block"> ...

Capybara's attach_file function is not properly activating the React onChange handler in Firefox

Currently, I am conducting tests on the file upload feature of a React-built page. The page includes a hidden file input field with an onChange event listener attached to it. Upon selecting a file, the onChange event is triggered and the file is processed ...

Issue with displaying info window when clicking on marker in react-google-maps

Seeking assistance in opening the info window of specific markers when clicked. All markers and map are displaying correctly, with correct titles appearing on hover. However, clicking a marker does not trigger the info window to show. The console confirms ...

React Native error - Numeric literals cannot be followed by identifiers directly

I encountered an issue while utilizing a data file for mapping over in a React Native component. The error message displayed is as follows: The error states: "No identifiers allowed directly after numeric literal." File processed with loaders: "../. ...

Tips for running a React custom hook selectively or within a specific function

I have created a unique custom hook to handle user redirection to the edit page. While on the index page, users can duplicate and delete items. The issue arises when deleting an item triggers the custom hook to redirect back to the edit page. I am looking ...

Conceal a section if the array is not defined

Hey there, I've got this piece of code for checking the status of a Twitch streamer. $(document).ready(function () { // some initializations here var login = ''; var twitchStatusLinks = $('.twitch-status'); var twitchStatus ...

Transforming a circular data structure into JSON format within Firebase

The data returned from firebase is causing an issue when I try to stringify it: JSON.stringify(data) // where data represents the returned object This results in the error: TypeError: Converting circular structure to JSON What is the correct way to hand ...

There seems to be a problem with the sorting functionality on the table in React JS,

My React table is functioning well with all columns except for the country name column. I double-checked the API and everything seems to be in order, but I'm stuck on how to troubleshoot this issue. const Table = () => { const[country, setCount ...

Can JSON be used to perform mathematical operations and calculations?

Utilizing the amazing json-server as my application's backend has been incredibly beneficial for custom data retrieval. However, it would be even more valuable if it supported calculations and expressions to mimic backend behavior. Consider this data ...

What is causing certain code to be unable to iterate over values in a map in TypeScript?

Exploring various TypeScript idioms showcased in the responses to this Stack Overflow post (Iterating over Typescript Map) on Codepen. Below is my code snippet. class KeyType { style: number; constructor(style) { this.style = style; }; } fu ...

JQuery is not able to render Hindi content properly

I am attempting to showcase some Hindi words using JQuery because these are essential contents that need to be displayed on every page of the website. Please note that this is a static website built with HTML and JQuery/JavaScript. Below is my JS file: in ...

Even though I have successfully compiled on Heroku, I am still encountering the dreaded Application Error

Looking for help with a simple express/node application to test Heroku? Check out my app.js: const express = require('express') const app = express() const port = '8080' || process.env.PORT; app.get('/', function (req, res) ...

Searching and replacing query strings in a URL using JQuery according to the chosen option in an HTML dropdown menu

Is there a way to use jQuery to dynamically change a specific value in the query string by finding and replacing that value based on the selection made from a dropdown menu on the webpage? For example: Imagine we have this query string on the current page ...