Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React.js error: The service worker navigation preload request was cancelled before 'preloadResponse' settled

I have an issue with my React application (with Redux Saga), I'm getting the console error:

The service worker navigation preload request was cancelled before 'preloadResponse' settled. If you intend to use 'preloadResponse', use waitUntil() or respondWith() to wait for the promise to settle.

I see this error on the console only on Chrome, not in Firefox or Edge. This error does not affect my application.

The following steps reproduce the error:

1. Main page upload.

enter image description here

2. Go to movie details page.

enter image description here

3. Go back to main page.

enter image description here

Main.jsx

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { mainActions } from '../../store/actions/actions';
import './Main.scss';
import { MoviesList, SearchPanel } from '../../components';

const propTypes = {};
const defaultProps = {};

class Main extends Component {

  constructor(props) {
    super(props);
    this.handleSearchTextChange = this.handleSearchTextChange.bind(this);
    this.handleLoadMoreButtonClick = this.handleLoadMoreButtonClick.bind(this);
    this.handleMovieClick = this.handleMovieClick.bind(this);
    this.handleFavoriteMovieClick = this.handleFavoriteMovieClick.bind(this);
  }

  componentDidMount() {
    this.handleComponentDidMount();
  }

  handleComponentDidMount() {
    const { moviesList } = this.props;
    if (!moviesList || moviesList.length <= 0) {
      this.getMovies(null, false);
    }
  }

  handleLoadMoreButtonClick() {
    this.getMovies(null, false);
  }

  handleMovieClick(e) {
    if (e.target.className === 'movie') {
      this.props.history.push(`/details/${e.currentTarget.dataset.id}`);
    }
  }

  handleSearchTextChange(e) {
    const { pageNumber, favoriteMoviesList } = this.props;
    this.props.onSearchTextChange({
      searchText: e.target.value,
      pageNumber: pageNumber,
      favoriteMoviesList: favoriteMoviesList
    });
  }

  handleFavoriteMovieClick(e) {
    const { id, name, posterId } = e.currentTarget.dataset;
    const { moviesList, favoriteMoviesList } = this.props;
    this.props.onUpdateFavoriteMovies({
      updatedMovie: { id: id, name: name, posterId: posterId },
      favoriteMoviesList: favoriteMoviesList,
      moviesList: moviesList
    });
  }

  getMovies(updatedSearchText, isSearchChange) {
    const { searchText, pageNumber, favoriteMoviesList } = this.props;
    this.props.onLoadMovies({
      pageNumber: pageNumber,
      favoriteMoviesList: favoriteMoviesList,
      updatedSearchText: isSearchChange ? updatedSearchText : searchText,
      isSearchChange: isSearchChange
    });
  }

  render() {
    const { searchText, isLoadingMoreMovies, isPager, moviesList } = this.props;
    return (
      <div className="main-area">
        <SearchPanel
          searchText={searchText}
          onSearchTextChange={this.handleSearchTextChange}
        />
        <MoviesList
          pageName='movies'
          moviesList={moviesList}
          isLoadingMoreMovies={isLoadingMoreMovies}
          isPager={isPager}
          onLoadMoreClick={this.handleLoadMoreButtonClick}
          onMovieClick={this.handleMovieClick}
          onFavoriteMovieClick={this.handleFavoriteMovieClick}
        />
      </div>
    );
  }
}

Main.propTypes = propTypes;
Main.defaultProps = defaultProps;

const mapStateToProps = (state) => {
  return {
    searchText: state.main.searchText,
    pageNumber: state.main.pageNumber,
    isLoadingMoreMovies: state.main.isLoadingMoreMovies,
    isPager: state.main.isPager,
    moviesList: state.main.moviesList,
    favoriteMoviesList: state.main.favoriteMoviesList
  };
};

const mapDispatchToProps = (dispatch) => {
  return {
    onLoadMovies: (request) => dispatch(mainActions.loadMovies(request)),
    onSearchTextChange: (request) => dispatch(mainActions.searchTextChange(request)),
    onUpdateFavoriteMovies: (request) => dispatch(mainActions.updateFavoriteMovies(request))
  };
};

export default connect(mapStateToProps, mapDispatchToProps)(Main);

Details.jsx

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { detailsActions, mainActions } from '../../store/actions/actions';
import './Details.scss';
import { ActorsList, ButtonClick, CrewsList, FeaturesList, PageTitle, ProductionsList, Rating, Trailer } from '../../components';
import movieUtils from '../../utils/movie.utils';

const propTypes = {};
const defaultProps = {};

class Details extends Component {
    constructor(props) {
        super(props);
        this.handleBackClick = this.handleBackClick.bind(this);
        this.handleFavoriteMovieClick = this.handleFavoriteMovieClick.bind(this);
        this.isFavorite = false;
    }

    componentDidMount() {
        this.handleComponentDidMount();
    }

    handleComponentDidMount() {
        if (this.props.moviesList.length <= 0) {
            this.handleBackClick();
            return;
        }
        const movieId = this.props.match.params.id;
        if (!movieId) {
            this.handleBackClick();
            return;
        }
        this.props.onLoadMovieDetails(movieId);
        this.updateIsFavorite(movieId);
    }

    numberWithCommas(number) {
        return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
    }

    updateIsFavorite(movieId) {
        this.isFavorite = this.props.favoriteMoviesList.findIndex(movie => parseInt(movie.id) === parseInt(movieId)) > -1;
    }

    handleBackClick() {
        this.props.history.push(`/`);
    }

    handleFavoriteMovieClick() {
        const { movie, moviesList, favoriteMoviesList } = this.props;
        this.props.onUpdateFavoriteMovies({
            updatedMovie: { id: movie.id, name: movie.title, posterId: movie.poster_path },
            favoriteMoviesList: favoriteMoviesList,
            moviesList: moviesList
        });
        this.updateIsFavorite(movie.id);
    }

    render() {
        const { movie, youtubeKey, credits } = this.props;
        if (!movie) {
            return null;
        }
        const { adult, poster_path, budget, genres, homepage, imdb_id, original_language, original_title,
            overview, popularity, production_companies, production_countries, release_date, revenue, runtime, spoken_languages,
            status, tagline, title, video, vote_average, vote_count } = movie;
        const genresText = genres.map(genre => genre.name).join(', ');
        const countriesText = production_countries.map(country => country.name).join(', ');
        const languagesText = spoken_languages.map(language => language.name).join(', ');
        const featuresList = [
            { item: 'Release Date', value: release_date },
            { item: 'Budget', value: `$${this.numberWithCommas(budget)}` },
            { item: 'Revenue', value: `$${this.numberWithCommas(revenue)}` },
            { item: 'Length', value: `${runtime} minutes` },
            { item: 'Popularity', value: popularity },
            { item: 'Original Title', value: original_title },
            { item: 'For Adults', value: adult ? 'Yes' : 'No' },
            { item: 'Original Language', value: original_language },
            { item: 'Spoken Languages', value: languagesText },
            { item: 'Countries', value: countriesText },
            { item: 'Status', value: status },
            { item: 'Is Video', value: video ? 'Yes' : 'No' }
        ];
        const linksList = [];
        if (homepage) {
            linksList.push({ id: 1, name: 'Homepage', url: homepage });
        }
        if (imdb_id) {
            linksList.push({ id: 2, name: 'IMDB', url: `https://www.imdb.com/title/${imdb_id}` });
        }
        const actorsList = movieUtils.removeDuplicates(credits ? credits.cast ? credits.cast : null : null, 'name');
        const crewsList = movieUtils.removeDuplicates(credits ? credits.crew ? credits.crew : null : null, 'name');
        return (
            <div>
                <section className="details-area">
                    <PageTitle
                        pageName='details'
                        pageTitle='Details'
                    />
                    <ul className="details-content">
                        <li className="details-left" style={{ backgroundImage: `url('https://image.tmdb.org/t/p/original${poster_path}')` }}></li>
                        <li className="details-right">
                            <h2>{title} ({release_date.substr(0, 4)})</h2>
                            <p className="genres">{genresText}</p>
                            <p className="description short">{tagline}</p>
                            <Rating
                                rating={vote_average}
                                votesCount={this.numberWithCommas(vote_count)}
                            />
                            <p className="description full">{overview}</p>
                            <div className="extra">
                                <FeaturesList
                                    featuresList={featuresList.slice(0, 5)}
                                    linksList={null}
                                    isFavorite={this.isFavorite}
                                    onFavoriteMovieClick={this.handleFavoriteMovieClick}
                                />
                                {youtubeKey && <Trailer
                                    youtubeKey={youtubeKey}
                                />}
                            </div>
                        </li>
                        <div className="extra-features">
                            <FeaturesList
                                featuresList={featuresList.slice(5, featuresList.length)}
                                linksList={linksList}
                                isFavorite={null}
                                onFavoriteMovieClick={null}
                            />
                            <ProductionsList
                                productionsList={production_companies}
                            />
                        </div>
                    </ul>
                </section>
                <section className="actors-area">
                    <PageTitle
                        pageName='actors'
                        pageTitle='Cast'
                    />
                    <ActorsList
                        actorsList={actorsList}
                    />
                </section>
                <section className="crew-area">
                    <PageTitle
                        pageName='crew'
                        pageTitle='Crew'
                    />
                    <CrewsList
                        crewsList={crewsList}
                    />
                </section>
                <ButtonClick
                    buttonText={'Back'}
                    buttonTitle={'Back'}
                    isLoading={false}
                    onClick={this.handleBackClick}
                />
            </div>
        );
    }
}

Details.propTypes = propTypes;
Details.defaultProps = defaultProps;

const mapStateToProps = (state) => {
    return {
        movie: state.details.movie,
        youtubeKey: state.details.youtubeKey,
        credits: state.details.credits,
        moviesList: state.main.moviesList,
        favoriteMoviesList: state.main.favoriteMoviesList
    };
};

const mapDispatchToProps = (dispatch) => {
    return {
        onLoadMovieDetails: (movieId) => dispatch(detailsActions.loadDetails(movieId)),
        onUpdateFavoriteMovies: (request) => dispatch(mainActions.updateFavoriteMovies(request))
    };
};

export default connect(mapStateToProps, mapDispatchToProps)(Details);

What I already looked in:
Getting The service worker navigation preload request was cancelled before 'preloadResponse' settled
https://docs.microsoft.com/en-us/answers/questions/108004/getting-the-service-worker-navigation-preload-requ.html
https://support.google.com/mail/thread/4055804?hl=en
https://love2dev.com/pwa/service-worker-preload/

I tried to put this on Details.jsx page, but it didn't work:

self.addEventListener('fetch', event => {
    event.respondWith(async function () {
        // Respond from the cache if we can
        const cachedResponse = await caches.match(event.request);
        if (cachedResponse) return cachedResponse; // Else, use the preloaded response, if it's there
        const response = await event.preloadResponse;
        if (response) return response; // Else try the network.
        return fetch(event.request);
    }());
});

self.addEventListener('activate', event => {
    event.waitUntil(async function () {
        // Feature-detect
        if (self.registration.navigationPreload) { // Enable navigation preloads!
            console.log('Enable navigation preloads!');
            await self.registration.navigationPreload.enable();
        } return;
    })();
});

How can I solve this issue? Thanks.

like image 702
Or Assayag Avatar asked Feb 08 '21 09:02

Or Assayag


People also ask

Why am I getting a navigation preload error in workbox?

When using workbox.navigationPreload.enable (), it throws this error in the console. The service worker navigation preload request was cancelled before 'preloadResponse' settled. If you intend to use 'preloadResponse', use waitUntil () or respondWith () to wait for the promise to settle.

How do I wait for a preload response to settle?

If you intend to use 'preloadResponse', use waitUntil () or respondWith () to wait for the promise to settle. · Issue #2883 · GoogleChrome/workbox · GitHub The service worker navigation preload request was cancelled before 'preloadResponse' settled.

What is navigationpreload object in service worker?

The navigationPreload object is a member of the service worker Registration object. self.addEventListener ( "activate", event => { event.waitUntil ( async function () { // Feature-detect if ( self.registration.navigationPreload ) { // Enable navigation preloads! console.log ( "Enable navigation preloads!"

How does the preloadresponse work?

Just like finding a match within a service worker cache the preloadResponse is asynchronous, returning a response object. Above is the standard service worker cache first, then network pattern. Now the pattern adds support for the preloadResponse.


1 Answers

Had same error, even my iframe wasn't loading..whatever video you are using from youtube use nocookie/embed in url. It's working for me.

Try changing https://www.youtube.com/watch?v=i8eBBG46H8A to

https://www.youtube-nocookie.com/embed/i8eBBG46H8A

Hope nocookie & embed helps..!!

like image 138
Punjab Avatar answered Sep 22 '22 02:09

Punjab