CloudCannon / pagefind

Static low-bandwidth search at scale
https://pagefind.app
MIT License
3.34k stars 100 forks source link

Getting TypeError: null is not an object (evaluating 's.filters') with pagefind.debouncedSearch #441

Closed earthboundkid closed 11 months ago

earthboundkid commented 11 months ago

If I pass any options to pagefind.debouncedSearch, it throws an error, TypeError: null is not an object (evaluating 's.filters'), but it doesn't throw that error if I call pagefind.search with the same options.

earthboundkid commented 11 months ago

I just manually recreate debouncedSearch, like

const asyncSleep = async (ms = 100) => {
  return new Promise((r) => setTimeout(r, ms));
};

let currentSearchID = 0;

// See https://github.com/CloudCannon/pagefind/issues/441
async function debouncedSearch(
  pf,
  term,
  options = {},
  debounceTimeoutMs = 300,
) {
  const thisSearchID = ++currentSearchID;
  await asyncSleep(debounceTimeoutMs);

  if (thisSearchID !== currentSearchID) {
    return null;
  }

  const searchResult = await pf.search(term, options);
  if (thisSearchID !== currentSearchID) {
    return null;
  }
  return searchResult;
}

it doesn't throw an error, which suggests to me there's some shenanigans going on with this being corrupted somehow.

earthboundkid commented 11 months ago

Adding pf.preload(term, options); (the equivalent of this.preload(term, options);) to the debouncedSearch above breaks it again. I think there's something wrong with preload's instance map where it can't deal with options when they're set.

danpls commented 11 months ago

You're right. I can reproduce this. The search function seems to hit the following if condition causing it to bail out and return null, which is exactly the same null that is responsible for the TypeError reported from the console.

https://github.com/CloudCannon/pagefind/blob/5bbc5a721b5ae8ae665b9ac82a318bec487e9d72/pagefind_web_js/lib/coupled_search.ts#L403-L406

I am unsure of the purpose of options.preload, but my guess is that it's been mistakenly set in this case. Removing the if condition from above seems to fix it for me, however I am not yet comfortable with the code base, so I doubt this is going to be the appropriate solution.

bglw commented 11 months ago

Ahh I see what has happened here.

https://github.com/CloudCannon/pagefind/blob/5bbc5a721b5ae8ae665b9ac82a318bec487e9d72/pagefind_web_js/lib/coupled_search.ts#L348-L351

The preload function is mutating the options object, rather than passing a new one down. Which causes the now-mutated options object to be passed to the search function, which returns null 😩

Will fix

danpls commented 11 months ago

Can confirm. This fixes it on my side.

earthboundkid commented 11 months ago

I’ll go ahead and close this issue, since it looks like #444 fixed it.

bglw commented 9 months ago

Released in v1.0.4 🎉