Migrating from v2 to v3
This doc guides you through migrating a project using Data Provider v2 to Data Provider v3.
Data Provider v3.0.0 introduced some breaking changes that require manual actions to complete a migration, but we published a version in Data Provider v2 that allows to perform a progressive migration. First, we will see all changes that have to be done, and afterwards we will give you some tips to achieve the migration progressively.
Selectors dependencies arguments
Why it was changed
In Data Provider v2 there was a clear differentiation between selector dependencies, and the last function provided to the selector, which was called the selector
method itself, and it was required always when creating a Selector. It was the function receiving all the results of the dependencies, so you could parse, modify or combine its data and return the result.
So, this method was receiving the results of the dependencies as different arguments, in the same order than the dependencies were declared, and as last argument, it was receiving the queryValue
, just in case you wanted to use it. On the contrary, the dependencies were receiving the queryValue
as first argument, and the results of the previous dependencies inside an array in the second argument.
In later V2 minor releases, the selector
method was allowed to return another dependencies as well (as the selector dependencies
can do). And the dependencies were allowed to return also plain values (as the selector
can do)
So, why not to unify the arguments of the dependencies
and the selector
method? In the end, the selector
was already another type of dependency
, able to do the same as a dependency
was. Then, the concept of selector
method was removed, and from v3, all arguments passed to the Selector
class are considered as dependencies
, except the last one in case it is a plain object, which remains being the selector options.
What was changed
Arguments of the dependencies in a Selector
A Selector dependency in v1 was receiving next arguments:
(queryValue, previousDependenciesResults) => {}
Note that previousDependenciesResults
was an array.
In v2 a Selector dependency receives next arguments:
(queryValue, [...dependenciesResults]) => {}
Where dependenciesResults
are different arguments with the results of previous dependencies as well.
Arguments of the last function in a Selector
The last function of a Selector in v1 was receiving next arguments:
([...dependenciesResults], queryValue) => {}
In v2 the last function becomes another dependency, so it receives next arguments:
(queryValue, [...dependenciesResults]) => {}
So, in the last function in a Selector you have to move the queryValue
argument from the last position (in case you were using it) to the first one.
v2 example
const booksOfAuthor = new Selector(
queryValue => author.query({ urlParams: { id: queryValue.id }}),
(queryValue, previousResults) => books.query({
queryString: { "author": previousResults[0].id }
}),
(authorResult, booksResults) => {
return booksResults.map(book => ({
...book,
authorName: authorResult.name,
}));
}
);
v3 example
const booksOfAuthor = new Selector(
queryValue => author.query({ urlParams: { id: queryValue.id }}),
(queryValue, authorResult) => books.query({
queryString: { "author": authorResult.id }
}),
(queryValue, authorResult, booksResults) => {
return booksResults.map(book => ({
...book,
authorName: authorResult.name,
}));
}
);
Selectors options
What was changed
reReadDependenciesMaxTime
option
The reReadDependenciesMaxTime
option in v2 was renamed to readAgainMaxTime
in v3 for better comprehension.
v2 example
selector.config({
reReadDependenciesMaxTime: 3000,
});
v3 example
selector.config({
readAgainMaxTime: 3000,
});
Provider arguments
A Provider class (or an origin addon class) in v1 was receiving next arguments:
new Provider("provider-id", { fooOption: "foo-value" })
In v2 a Provider receives the id as a property in the options object, that now has to be passed as first argument.
new Provider({ id: "provider-id", fooOption: "foo-value" })
This was made because the id
is optional when creating providers.
For those maintaining an origin addon, they have to take into account that also the
createChildMethod
has changed its arguments and it also receives only the(options, queryValue)
arguments in v3, while in v2 version it was receiving(id, options, queryValue)
. Read more about how to make an addon compatible with v2 and v3
How to migrate progressively
Install v2.10.0 version
The @data-provider/core@2.10.0
version exposes both versions of the Selector
class, so you can use the old API in some parts of your project while progressively migrate other parts to the new API.
npm i --save @data-provider/core@2.10.0
Install addons compatible versions
The Provider
class in this version also accepts defining the id
as first argument or as second argument, but note that you usually don't use the Provider
class directly, but origin addons classes. So, you'll have also to install the addons versions that are compatible with v2 and v3 to be able to migrate progressively.
Next addons versions are compatible with v2 and v3:
@data-provider/memory@2.1.1
@data-provider/browser-storage@2.3.1
@data-provider/axios@2.2.1
@data-provider/prismic@2.1.1
Configure renamed option
The reReadDependenciesMaxTime
option can be used only in selectors created with the old Class, while in the new ones only the readAgainMaxTime
option will have effect. So, if you are using the providers
handler to configure all selectors at a time, and you are using this option, now you'll have to set both options:
providers.getByTag("selector").config({
reReadDependenciesMaxTime: 3000,
readAgainMaxTime: 3000,
});
Use new Selector
Now you can use the new exported SelectorV3
class in those selectors you want to start migrating:
import { Selector, SelectorV3 } from "@data-provider/core";
Or, even better, if you plan to migrate one full file at a time, you could do:
import { SelectorV3 as Selector } from "@data-provider/core";
Both selectors can be used as dependency of the other selector version, so they are fully compatible and the migration can be achieved progressively, migrating only those selectors you want.
Install v3.x version
When you use the Selector
class in the 2.10.0 version you'll see a deprecation warning in the console. You'll also receive warnings when using old Provider
arguments. So you'll know you are ready to update to v3 when you stop receiving this type of warnings.
Once you have migrated all your Selectors and you are not using any more the Selector v2, you could simply update your dependency to v3:
npm i --save @data-provider/core@3.x
And change your SelectorV3
imports to Selector
again:
import { Selector } from "@data-provider/core";
How to make an addon compatible with v2 and v3
This section is intended only for those maintaining Data Provider origin addons. Here is explained how to publish a version compatible with v2 and v3, allowing users to migrate progressively as described in the previous section.
You will only have to change something if you are defining your own constructor
or createChildMethod
in your addon. If not, you don't have to do anything.
Update dependencies
The @data-provider/core@2.10.0
version exposes a helper to facilitate addons to accept arguments in v2 or v3 format. First of all, you should change you peerDependencies
to only accept this version, and your devDependencies
to use it in your tests:
{
"peerDependencies": {
"@data-provider/core": ">=2.10.0"
},
"devDependencies": {
"@data-provider/core": "2.10.0"
}
}
Modify constructor
Then, you have to use the mentioned helper to allow users to pass arguments in v2 or v3 formats.
If your addon constructor
looked like:
import { Provider } from "@data-provider/core";
export class MyAddon extends Provider {
constructor(id, options, queryValue) {
console.log(`The id is ${id}`);
super(id, options, queryValue);
}
}
Then it should look like:
import { Provider, providerArgsV3 } from "@data-provider/core";
export class MyAddon extends Provider {
constructor(...args) {
const [id, options, queryValue] = providerArgsV3(args);
console.log(`The id is ${id}`);
super({ ...options, id }, queryValue);
}
}
This will make your addon compatible with v2 and v3. It is recommended that you publish a minor version with these changes before completely migrate it to v3.
Migrate to v3
Once you have published your compatible minor version allowing users to perform a progressive migration, you can now update your dependencies to v3:
{
"peerDependencies": {
"@data-provider/core": "3.x"
},
"devDependencies": {
"@data-provider/core": "3.0.0"
}
}
Modify your constructor
to use the new v3 arguments:
import { Provider } from "@data-provider/core";
export class MyAddon extends Provider {
constructor(options, queryValue) {
console.log(`The id is ${options.id}`);
super(options, queryValue);
}
}
Modify your createChildMethod
in case you have it defined:
import { Provider } from "@data-provider/core";
export class MyAddon extends Provider {
createChildMethod(options, queryValue) {
console.log(`Creating a child with id ${options.id}`);
return this.constructor(options, queryValue);
}
}