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

Plugin instance is ignoring new path function set with InfiniteScroll.prototype.option method #936

Open
luxplanjay opened this issue Jan 15, 2021 · 5 comments

Comments

@luxplanjay
Copy link

luxplanjay commented Jan 15, 2021

What it says in the description. My case is a form where a user can enter a search term for an api request. Every new form submission I need to reset path option to generate proper URL with query param.

Made a simple live example where after infScroll.option({path() {}}) the instance is still using the path function that it was initialized with. Here's a link to CodePen.

PS: Under the hood option method is using Object.assign and it actually works fine with other options, but for some reason ignores new path function.

PSS: Perhaps I'm supposed to destroy and reinitialize a new instance on every form submission?

@desandro
Copy link
Member

Thanks for reporting this issue! You are correct, the path behavior will not be changed after you re-set path. You actually need to trigger an undocumented method updateGetPath to have your change take effect. That's the technical solution

// set new path option
infScroll.option.path = 'new path';
// update behavior
infScroll.updateGetPath();

Since your demo is already using a function, another solution is to update variables used within the function, so the same function could be used. See CodePen

@luxplanjay
Copy link
Author

luxplanjay commented Jan 18, 2021

Since your demo is already using a function, another solution is to update variables used within the function, so the same function could be used. See CodePen

So what you are saying is I basically need a global variable, which will work in this case for sure. But what if instance initialization is done in a separate file inside a function where I have no way to access anything global. I can «hack» it with object reference and а function that accepts options object.

// this lives in some initscroll.js
export default function initiInfScroll(options) {
  return new InfiniteScroll(".js-container", {
    path() {
      return options.pathUrl;
    }
  });
}

// app.js
import initiInfScroll from 'path/to/initscroll';

const infScrollOptions = {
  pathUrl: 'https://jsonplaceholder.typicode.com/todos/1'
}
const infScroll = initiInfScroll(infScrollOptions);

document.querySelector(".js-change-path-btn").addEventListener("click", () => {
  infScrollOptions.pathUrl = "https://jsonplaceholder.typicode.com/todos/2";
});

But this just feels so wrong. Mutating cross-module object reference is not exactly safe.

Actually doing some monkey patching feels better and kinda ok, given the situation.

// Adding pathUrl field to this instance, so there will be no prototype pollution
// and then using it on the instance
const instance = new InfiniteScroll(".js-container", {
    path() {
      return this.pathUrl ?? '/1'
    },
})

// And then just change it when needed
instance.pathUrl = '/2'

Are there any plans in the API to support this case (which is very common to be honest) or monkey patching is the way?

@desandro
Copy link
Member

But what if instance initialization is done in a separate file inside a function where I have no way to access anything global.

In this case, I recommend you trigger updateGetPath after setting a new path.

@luxplanjay
Copy link
Author

In this case, I recommend you trigger updateGetPath after setting a new path.

Will try and get back to you with results.

@Erwane
Copy link

Erwane commented May 18, 2021

Hi. Got same issue, and add another problem about currentIndex

My index have form, loading content thrue Ajax. I update path like this :

        $(document).on('loaded.index.app', (event, body) => {
            if (body.path) {
                console.log("new path=" + body.path);
                this.infinite.options.path = body.path;
                this.infinite.updateGetPath();
            }
        })

Here the process

first load, Initialize infinite-scroll

optPath=/fr/bands/France.json?page={{#}}; nextIndex=2
core.js:207 optPath=/fr/bands/France.json?page={{#}}; nextIndex=2
core.js:153 [InfiniteScroll] initialized. on card-index bands

Add ar in query search and press button.

infinite.js:23 new path=/fr/bands/France.json?q=ar&page={{#}}

Scroll down

core.js:153 [InfiniteScroll] scrollThreshold
core.js:207 optPath=/fr/bands/France.json?page={{#}}; nextIndex=2
core.js:153 [InfiniteScroll] request. URL: /fr/bands/France.json?page=2
core.js:153 [InfiniteScroll] load. Annuaire des groupes - France. URL: /fr/bands/France.json?page=2

Scroll up, change query search to b Setting new path

infinite.js:23 new path=/fr/bands/France.json?q=b&page={{#}}
core.js:153 [InfiniteScroll] scrollThreshold
core.js:207 optPath=/fr/bands/France.json?page={{#}}; nextIndex=3
core.js:153 [InfiniteScroll] request. URL: /fr/bands/France.json?page=3
core.js:153 [InfiniteScroll] load. Annuaire des groupes - France. URL: /fr/bands/France.json?page=3

getPath and index are not reset.
Maybe a reset() method would be cool ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

3 participants