inertia icon indicating copy to clipboard operation
inertia copied to clipboard

Bug in $Inertia.

Open heleonprime opened this issue 3 years ago • 2 comments

Versions:

  • @inertiajs/inertia version: 0.11.0
  • @inertiajs/inertia-vue3 version: 0.6.0

Hello. I got the same issue like here in my code, but not with request sending functions. I'm trying to change page state when changing table ordering. I've tried like this

this.$inertia.pushState(this.$page)

Then i found that inside inertia's pushState method there's also this.page update, And then i've tried to do it in my component on click:

this.$page.url = this.pageBaseUrl + this.getUrlParams(pg);
this.$inertia.page = {...this.$page};
history.replaceState({}, '', this.$page.url);

And it worked, but until i've tried to scroll the page When i scroll the page i got image And then i found that the problen is in this.$inertia.page = {...this.$page}; string, if i comment it the error's disappear

How can i set the page properly. When i'm trying to set the state without setting the page - the url state refreshes to prevoius state on scroll. Why the scroll changes the state?

Here's the part of my code, there's a many logs, i'll remove'em later, but now it halped me to find this problem place

    l(...messages)
    {
      if(this.debug)
      {
        console.log(...messages);
      }
    },
    reset() {
      this.form = mapValues(this.form, () => null)
    },
    toggleOrder(name)
    {
      this.l('getUrlParams');
      this.l('     field name', name);
      this.l('     field name now', this.form.order[name]);
      if(this.form.order[name])
      {
        if(this.form.order[name] === 'asc')
          this.form.order[name] = 'desc'.toLowerCase();
        else if(this.form.order[name] === 'desc')
          delete this.form.order[name];
      }
      else
        this.form.order[name] = 'asc'.toLowerCase();
      this.l('     field name after', this.form.order[name]);
      this.l('     inithializing getList with page = 1');
      this.getList(1)
    },
    addHistory(pg)
    {
      this.l('getUrlParams');
      this.l('     pg:', pg);
      this.l('     this.getUrlParams(pg)', this.getUrlParams(pg));
      this.l('pushState:', this.$inertia.pushState);
      this.$page.url = this.pageBaseUrl + this.getUrlParams(pg);
      this.$inertia.page = {...this.$page};
      this.l(this.$page.url);
      this.l(this.$page.target);
      this.l({...this.$page});
      this.l(JSON.parse(JSON.stringify(this.$page)));
      //history.replaceState({}, '', this.$page.url)

      //this.$inertia.pushState(this.$page) /*{} ,null, this.pageBaseUrl + this.getUrlParams(pg)*/
      this.l('$inertia:', this.$inertia);
    },
    getUrlParams(pg){
      this.l('getUrlParams');
      this.l('     pg: ', pg);
      this.l('!!!!!TRYING URLSearchParams():', new URLSearchParams(this.form).toString());
      let params = [];
      let orderKeys = Object.keys({...this.form.order});
      this.l('     orderKeys length: ', orderKeys.length);
      if(orderKeys.length)
        orderKeys.forEach((val) => {
          params.push(`order[${val}]=${this.form.order[val]}`);
        });
      if (this.form.search)  params.push(`search=${this.form.search}`);
      if (this.form.trashed) params.push(`trashed=${this.form.trashed}`);
      if (this.form.active)  params.push(`active=${this.form.active}`);
      if (pg) params.push(`page=${pg}`);
      this.l('     all params: ', params);
      this.l('     params length: ', params.length);
      this.l('     params string: ', params.length ? `?${params.join('&')}`: '');
      if (params.length) return `?${params.join('&')}`;
      return '';
    },
    getList(pg)
    {
      this.l('getList');
      this.l('     pg:', pg);
      this.l('     nulling last_page:', !pg || pg === 1);
      if(!pg || pg === 1) this.last_page = null;
      this.l('     loading:', this.loading);
      this.l('     last_page:', this.last_page);
      this.l('     current_page:', this.current_page);
      this.l('     can go on:', !this.loading && (!this.last_page || ( this.last_page && this.current_page < this.last_page)));
      if(!this.loading && (!this.last_page || ( this.last_page && this.current_page < this.last_page)))
      {
        this.loading = 1;
        this.l('     loading:', this.loading);
        this.form.page = pg;
        this.l('     form.page:', this.form.page);
        this.l('     sending request');
        this.$http.get('/api/parsers' + this.getUrlParams(pg),{
          withCredentials: true,
          //params: this.form,
        }).then((response) => {
          this.l('     got response', response);
          this.l('     rewriting pages list:', !pg || pg === 1);
          if(!pg || pg === 1) this.ps = response.data.parsers.data;
          else this.ps = this.ps.concat(response.data.parsers.data);

          this.current_page = response.data.parsers.current_page;
          this.l('     current_page:', this.current_page);
          this.last_page = response.data.parsers.last_page;
          this.l('     last_page:', this.last_page);
          this.psc = response.data.count;
          this.l('     pages count:', this.psc);
          this.loading = 0;
          this.l('     loading:', this.loading);
          this.l('     inithializing addHistory');
          this.addHistory(pg);
        });
      }
    },
    onScroll(event) {
      this.l('onScroll');
      this.lastPageIsVisible = useElementVisibility(this.lastPage).value;
      this.l('     lastPageIsVisible:', this.lastPageIsVisible);
      if(this.lastPageIsVisible)
      {
        this.l('     inithializing getList with page = ' + this.current_page + 1);
        this.getList(this.current_page + 1);
      }
    },

Here's what i got on scroll image

heleonprime avatar Jul 15 '22 18:07 heleonprime

Just did it with

this.$inertia.page.url = this.pageBaseUrl + this.getUrlParams(pg);
this.$inertia.replaceState(this.$inertia.page)

heleonprime avatar Jul 16 '22 08:07 heleonprime

Thanks @heleonprime! This helped me resolve an issue where I was also attempting to modify the browser's history via pushState to adjust query parameters from a Vue component.

Previously, Inertia would ignore my custom history.pushState. When a new history record was pushed and I clicked on another inertia-link in my view, the query params would disappear for a second, and then navigate me to the new page. This would break back/forward buttons in browser.

Here is what I had:

updateQueryParams(params) {
    window.history.pushState({}, '', window.location.pathname + '?' + params.toString());
}

I've now updated it to:

import { Inertia } from '@inertiajs/inertia';

updateQueryParams(params) {
    const url = window.location.pathname + '?' + params.toString();

    Inertia.page.url = url;

    Inertia.pushState(Inertia.page);
}

Which now properly update's Inertia's internal tracking of the page update, and the back/forward buttons work 🎉

My use-case for updating query params like this is for tracking the sort order of a client-side rendered data table. A user needs to be able to click a header to sort the table and then be able to refresh the browser or click the browser back button to bring them to the page with their sort alterations restored to that data table.

stevebauman avatar Sep 26 '22 18:09 stevebauman

Hey! Thanks so much for your interest in Inertia.js and for sharing this issue/suggestion.

In an attempt to get on top of the issues and pull requests on this project I am going through all the older issues and PRs and closing them, as there's a decent chance that they have since been resolved or are simply not relevant any longer. My hope is that with a "clean slate" me and the other project maintainers will be able to better keep on top of issues and PRs moving forward.

Of course there's a chance that this issue is still relevant, and if that's the case feel free to simply submit a new issue. The only thing I ask is that you please include a super minimal reproduction of the issue as a Git repo. This makes it much easier for us to reproduce things on our end and ultimately fix it.

Really not trying to be dismissive here, I just need to find a way to get this project back into a state that I am able to maintain it. Hope that makes sense! ❤️

reinink avatar Jul 28 '23 01:07 reinink