algoliasearch-client-javascript icon indicating copy to clipboard operation
algoliasearch-client-javascript copied to clipboard

Hosts are not set if SearchOptions.hosts is undefined

Open bodinsamuel opened this issue 5 years ago • 7 comments

Because the way of how spread work and how typescript handles Readonly it's quite hard to set hosts dynamically.

const hosts; // undefined by default
const test = { hosts: [], ...{ hosts } };

// Will yield `{ hosts: undefined }`

It's problematic because, AlgoliaSearchOptions.hosts is readonly so if you want to do conditional change it won't let you do it. And because we don't have access to the default values it can make the code less clear to avoid this problem

Fail

 let hosts?: HostOptions[];

 if (appId.startsWith('1234')) {
   hosts = [{ ... }];
 }

const client = algoliasearch(appId, apiKey, {
    hosts,
});
// This will fail without warning

pass

 // meh
 if (appId.startsWith('1234')) {
  const client = algoliasearch(appId, apiKey, {
    hosts,
  });
 } else {
  const client = algoliasearch(appId, apiKey);
}
const options?: AlgoliaSearchOptions;

 if (appId.startsWith('1234')) {
    // @ts-ignore sad :(
   options.hosts = [{ ... }];
 }

const client = algoliasearch(appId, apiKey, options);

bodinsamuel avatar May 28 '20 19:05 bodinsamuel

You need to change hosts dynamically @bodinsamuel?

nunomaduro avatar May 29 '20 18:05 nunomaduro

That's intentional, and it brings advantages: Makes the immutable client without having us applying deep copies on the giving options.

We don't wanna people being able to change options once the client is initialised. Sorry. 👍

nunomaduro avatar Jun 09 '20 15:06 nunomaduro

I think the error is clearer here:

const hosts = appId.startsWith('1234') ? [{...}] : undefined

const client = algoliasearch(appId, apiKey, {
  hosts
});

with this code, the hosts value in the client will be undefined, instead of the default value because of

https://github.com/algolia/algoliasearch-client-javascript/blob/a91bf8e611e9892d26e13aca67bbba5bec3b15f5/packages/client-search/src/createSearchClient.ts#L36

this line will override the default hosts with hosts: undefined because of how spread works.

The solution for a user right now is to not pass hosts at all in the object, but the only way to do that is e.g. like this, which isn't so clean:

const client = algoliasearch(
  appId,
  apiKey,
  appId.startsWith('1234') ? { hosts: [{...}] } : {}
);

I'm not sure what the solution is here, but it might be to not rely on spread / Object.assign semantics where undefined overrides a value

Haroenv avatar Jun 09 '20 15:06 Haroenv

Going to re-read this issue tomorrow morning.

nunomaduro avatar Jun 09 '20 15:06 nunomaduro

thanks for the clarification @Haroenv 👌

bodinsamuel avatar Jun 09 '20 18:06 bodinsamuel

Aaaaaaaah.

nunomaduro avatar Jun 10 '20 14:06 nunomaduro

Well, got it. This is a good to have, not urgent at the moment tho.

nunomaduro avatar Jun 10 '20 15:06 nunomaduro