Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change history state during navigation, break page.js #293

Open
pierissimo opened this issue Jul 8, 2015 · 14 comments · May be fixed by #558
Open

Change history state during navigation, break page.js #293

pierissimo opened this issue Jul 8, 2015 · 14 comments · May be fixed by #558
Labels

Comments

@pierissimo
Copy link

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
Copy link
Author

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

@aaronshaf
Copy link
Contributor

+1

@ryanwild
Copy link

ryanwild commented Feb 21, 2018

Updating page to the latest version solved the problem for me

@alephnode
Copy link

alephnode commented Jan 23, 2019

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);

@dman777
Copy link

dman777 commented Jan 27, 2019

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
Copy link

dman777 commented Feb 2, 2019

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
Copy link

dman777 commented Feb 3, 2019

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
Copy link

dman777 commented Feb 9, 2019

Anyone?

@dman777
Copy link

dman777 commented Feb 9, 2019

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
Copy link

dman777 commented Feb 9, 2019

Anyone?

@matthewp
Copy link
Collaborator

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

@dman777
Copy link

dman777 commented Feb 15, 2019

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
Copy link

dman777 commented May 5, 2019

Hi, any luck with this?

@dman777
Copy link

dman777 commented May 5, 2019

I'll paypal $50.00 to fix this bug

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
6 participants