page.js icon indicating copy to clipboard operation
page.js copied to clipboard

Change history state during navigation, break page.js

Open pierissimo opened this issue 10 years ago • 14 comments

Hi! I have to change history state during the change of a slide of a slider in my webpage. I use history.js:

History.pushState({slide:1}, "Slide 1", "/slide/1");

I also have a route registered with page.js:

page(['/slide', '/slide/:num'], function(ctx, next){ //things  });

When i use back and forward browser button, i got this error: Uncaught TypeError: Cannot read property '0' of undefined The error is from the page.js file, in this function, at the second line:

function Context(path, state) {
    if ('/' === path[0] && 0 !== path.indexOf(base)) path = base + (hashbang ? '#!' : '') + path;
    var i = path.indexOf('?');

    this.canonicalPath = path;
    this.path = path.replace(base, '') || '/';
    if (hashbang) this.path = this.path.replace('#!', '') || '/';

    this.title = document.title;
    this.state = state || {};
    this.state.path = path;
    this.querystring = ~i ? decodeURLEncodedURIComponent(path.slice(i + 1)) : '';
    this.pathname = decodeURLEncodedURIComponent(~i ? path.slice(0, i) : path);
    this.params = {};

    // fragment
    this.hash = '';
    if (!hashbang) {
      if (!~this.path.indexOf('#')) return;
      var parts = this.path.split('#');
      this.path = parts[0];
      this.hash = decodeURLEncodedURIComponent(parts[1]) || '';
      this.querystring = this.querystring.split('#')[0];
    }
  }

Anyone knows how i can manipulate history state, while using page.js? Thanks

pierissimo avatar Jul 08 '15 10:07 pierissimo

No one? There is not supported way to push a state and made it working with page.js?

pierissimo avatar Jul 13 '15 08:07 pierissimo

+1

aaronshaf avatar Dec 06 '15 01:12 aaronshaf

Updating page to the latest version solved the problem for me

ryanwild avatar Feb 21 '18 09:02 ryanwild

FWIW, adding a path property to the first argument passed to pushState() helped when this error arose in my project.

ex:

  let newUrl = window.location.href + '?foo=bar';
  window.history.pushState({path: newUrl}, null, newUrl);

alephnode avatar Jan 23 '19 18:01 alephnode

I am hitting this also(latest 1.10.*)

Changing the key to path fixes the error, but it causes the history state to not be there when I hit the back button.

const obj = { 'dolphin': 'all-listings'};
window.history.pushState(obj, 'all-listings', `all-listings?${queryString}`

dman777 avatar Jan 27 '19 21:01 dman777

I am using pushstate for my SPA app... where when a user consumes a api for a search, I update the url query string with the search params without reloading the page.

Anyone know how I can do this without pushState so page.js won't break? This has put me in a bind.

dman777 avatar Feb 02 '19 02:02 dman777

I see that a possible solution would be to use the pushState method that is binded to context object. Since page is global, how could I access context.pushState() outside a page() function?

Here is the snippet where I consume a api and I want to sync the url to resemble the search:

  _sendSearchRequestRaw(queryString) {
    this.loader = true;
    this.listings = [];

    const obj = { 'dolphin': 'all-listings'};
    window.history.pushState(obj, 'all-listings', `all-listings?${queryString}`);

    const request =
      this.createRequest(`${this.HOST}${this.LISTINGS}?${queryString}`);

    return fetch(request)
      .then(this.fetchError)
      .then(this.json)
      .then((response) => {
        this.loader = false;
        this._populateListings(response);
      })
      .catch((e) => {
        console.log('fetch error get listings ' + e);
      }

dman777 avatar Feb 03 '19 22:02 dman777

Anyone?

dman777 avatar Feb 09 '19 03:02 dman777

Anyone? I'm going have to rip out the whole routing system and replace it because of this bug. It would be nice if the maintainers could offer suggestions or reason why this bug still exists.

dman777 avatar Feb 09 '19 03:02 dman777

Anyone?

dman777 avatar Feb 09 '19 22:02 dman777

Can you produce a code example or test for what is failing? I can't tell from the comments.

matthewp avatar Feb 10 '19 00:02 matthewp

Than you for your reply.

This is how I sync the api query string with the url

    const obj = { path: 'all-listings'};
    this.urlHack = `all-listings?${queryString}`
    window.history.replaceState(obj, '', this.urlHack)

And here are the two routes involved:

page('/all-listings', function() {
  app.route = 'all-listings';
});

page('/single-listing/:listingNumber', function(context) {
  const listingNumber = context.params.listingNumber;
  app.route = 'single-listing';
  app.shadowRoot.querySelector('single-listing').getListing(listingNumber);
});

```. 

So if I:
1) Set the url with window.history while I am at `all-listings` 
2) Go to single listings
3) Hit the back button 

page.js errors out with the `Uncaught TypeError: Cannot read property '0' of undefined`

dman777 avatar Feb 15 '19 00:02 dman777

Hi, any luck with this?

dman777 avatar May 05 '19 17:05 dman777

I'll paypal $50.00 to fix this bug

dman777 avatar May 05 '19 17:05 dman777