Skip to main content

Migrating to version 2.0

Background

Version 2.0 of the SDK contains some rewrites to make the SDK a little bit more streamlined to work with and consistent, in particular regarding Catalogue- and Product Parameters.

CID

The CID is the ID of a Portfolio. A Portfolio contains one or more Catalogues. These Catalogues are not guaranteed to have globally unique IDs. Having Catalogues with same ID has occasionally been used as a feature when using CET Designer, as it creates a type of merged Catalogues. However, it does not work well in Stage. In the current version of the API it is not possible to use the CID to distinguish between different Catalogues or Products with the same parameters.

As a first step to remedy this CID is now part of the URLs and passed along with other parameters in the example-app.

Summary

The URL change might not affect you much if you have your own type of URLs (most customers do). Passing along the CID you will however have to do to fulfill the type requirements. As the CID is not at this point actually sent to the servers you would currently get by with passing for example -1, but we do recommend you use the real CID for future compatibility.

Lang

Catalogues can be translated to multiple languages. While there is support in the API for fetching Table of Contents and Products there is no support in example-app for selecting languages. As a step towards this language is now included in the URLs in example-app.

Summary

The URL change might not affect you much if you have your own type of URLs (most customers do). You may not have to do much, except for Parameter Passing (see below).

DTO prefix in names

The API exposes a number of data types. The prime purpose of these is for the API calls, but they are also where convenient used further into the SDK. It used to be no special naming distinction for these types, which meant they often had names that you would also want to use for, let's say a complex object in your implementation. That could be solved by name spacing (like CatalogueAPI.Feature) but it is easy to make annoying mistakes when multiple commonly used types have the same name. Internally in the SDK we have largely solved it by prefixing types with Cfg (like CfgFeature).

With this version we add DTO as a prefix to all types (and interfaces) in the API. This makes the intent of these objects clearer.

Cfg is still commonly used as a prefix in the Stage code, we make no changes there.

Summary

You will need to add Dto as a prefix to all types (and interfaces) that you have referenced in the API.

Parameter passing

Parameters identifying a Product or a Catalogue have been passed along though the call chains in the SDK in different ways, sometimes as single arguments, sometimes collected in objects, sometimes as mixes of the two. We have now moved over to sending the parameters in objects as far as possible.

Let's use the CfgProduct.make call as an example. It used to be:

CfgProduct.make(
api,
lang,
{
enterprise,
prdCat,
prdCatVersion,
vendor,
priceList,
},
partNumber
);

So, catalogue parameters collected, but lang and partNumber as separate arguments.

It is now:

CfgProduct.make(api, prodParams);

where prodParams is a DtoProductParamsWithCidAndLang object containing all parameters.

The code becomes cleaner, and in many cases you can just pass the object along.

Creating a more specific object, like a DtoProductParamsWithCidAndLang from a DtoCatalogueParamsWithCidAndLang and a partNumber is easy using spread operators:

function x(catParams: DtoCatalogueParamsWithCidAndLang, partNumber: string) {
const prodParams: DtoProductParamsWithCidAndLang = { ...catParams, partNumber };
}

Functional Components in React

React (and a number of frameworks) base their knowledge of then the DOM needs to update around updated object references.

Hooks in React, such as useEffect can be given a dependency array of object so that the hook only updates if any of these have changed.

As we have to create the params objects someplace care has to be taken so that we do not end up triggering rerenders all the time.

We have created the support function useMemoCatalogueParams, useMemoCatalogueParamsWithLang, useMemoProductParams and useMemoProductParamsWithLang to help with this. Their output will stay the same object, as long as the parameters in the incoming object are the same.

So, the output will be as stable as it can be.

The opposite problem to unnecessary rerenders happening can also happen.

Don't change the values inside an object to reuse it. The reference to the object will stay the same and so Hooks may not be triggered.

If you want to use data from your existing object you could do something like:

const myNewObject = { ...oldObject, partNumber: newPartNumber };

The members will be (shallow) copied, and then we overwrite partNumber with the new one.

Summary

There will be fewer arguments going into functions and Functional Components in many places. Usually it is just a matter of collecting these into objects which are passed along. Make sure that you use the memoizing functions mentioned above in strategic places (like when you create the object) to avoid unnecessary rerenders.

getApiSelection and setApiSelection removed from CfgProductConfiguration

...or at lease removed from the public interface.

In the early days of Stage it used to be that if one wanted to copy the entire Configuration of a Product one would do this on an instance of the CfgProductConfiguration object. Since we added support for Additional Products these manipulations should be done on the CfgProduct.

The calls on the CfgProduct object handles Additional Products recursively and properly takes care of validation calls to the server.

To replace calls on CfgProductConfiguration you can use getApiSelection, setApiSelection, getDtoConf and setDtoConf on CfgProduct. The last two use a new format for Product Configuration, design to be easier to read and with more explicit data when it comes to Features.

Initial Product Configuration now natively supported

We know that a fairly frequent use case is having an initial Product Configuration that is to be set on your Product. It used to be that this had to be done by first loading the Product, then applying the Product Configuration using setApiSelection or setDtoConf, then showing the Product. It is now possible to pass an initial Product Configuration directly when creating the Product.

CfgProduct.make(api, prodParams, undefined, initialProdConf);