The DispenseExtensionManager is responsible for managing the extension points that are specific to the Dispense application.

Methods

  • Maps data into the IngredientModel

    It is common for the ingredient data provided by the ingredient service to be augmented with additional properties that are not provided by the base KOS Ingredient model. The IngredientMapper extension point allows for the data to be mapped into the IngredientModel and the IngredientModel.data property to be augmented with additional properties.

    Parameters

    • ingredientDataMapper: IngredientDataMapper<Record<string, any>>

    Returns DispenseExtensionManager

    Example

    The following example shows how to map the data from the service response into the IngredientModel. The context is provided by the IngredientLoader extension point with its data being used to optionally augment the ingredient data.

    The result of the mapping will be available in the data property of the IngredientModel.

    In this case the IngedientReponseData interface represents the data being returned by the ingredient service and the IngredientData interface represents the data that will be available in the IngredientModel.data property. The ingredientDataMapper is responsible for mapping from one format to the other.


    interface IngredientResponseData extends NozzleServices.IngredientResponse {
    chilled: boolean;
    carbonated: boolean;
    highYield: boolean;
    }

    interface IngredientData {
    chilled: boolean;
    carbonated: boolean;
    highYield: boolean;
    }

    export const ingredientDataMapper = async (
    data: IngredientResponseData,
    context: IngredientContext
    ): Promise<IngredientData> => {
    return {
    chilled: data.chilled,
    carbonated: data.carbonated,
    highYield: data.highYield,
    }
    }
  • Loads data that will be provided as context into the IngredientMapper

    Parameters

    • ingredientLoader: DataLoader

    Returns DispenseExtensionManager

    Example

    The following example shows how to load the brandset data, normalize it into a map and then provide it back to the framework where it can be used by the other extension points.

    In the ingredient container model, the data is provided to the IngredientMapper extension point in order to augment ingredient data and also loaded into the ingredient container model context in order to make the data available throughout the code.

     export const ingredientContextLoader = async (): Promise<BeverageContext> => {
    const response = await kosFetch('kos:/system/some/ingredient/endpoint.json');

    if (response.status !== 200) {
    KosLog.error('Failed to load ingredient data');
    return {};
    }
    const json = await response.json();
    return json;
    };
  • Maps data into the AvailabilityModel

    Parameters

    • availabilityMapper: AvailabilityDataMapper<Record<string, any>, GroupBeverageResponse>

    Returns DispenseExtensionManager

    Example

    The following example shows how to map the data from the service response into the AvailabilityModel. The context is provided by the AvailabilityLoader extension point with its data being used to augment the availability data.

    The result of the mapping will be available in the data property of the AvailabilityModel.

    export const beverageDataMapper = async (
    data: NozzleServices.BeverageResponse,
    context: BeverageContext
    ): Promise<BeverageData> => {
    const id = data.altId;
    const iconUrl = encodeURI(
    `http://localhost:8081/system/brandset/${context?.[id]?.icon}`
    );
    const cuiColorCode = context?.[id]?.cuiColorCode
    ? context?.[id]?.cuiColorCode
    : '';
    return { iconUrl, cuiColorCode };
    };
  • Loads data that will be provided as context into the AvailabilityMapper

    Parameters

    • availabilityLoader: DataLoader

    Returns DispenseExtensionManager

    Example

    A common use case is to load brandset data that is UI specific and not provided directly by the Java service.

    The following example shows how to load the brandset data, normalize it into a map and then provide it back to the framework where it can be used by the other extension points.

    In the nozzle model, the data is provided to the AvailabilityMapper extension point in order to augment availability data and also loaded into the nozzle model context in order to make the data available throughout the code.

     export const beverageContextLoader = async (): Promise<BeverageContext> => {
    const response = await kosFetch('kos:/system/brandset/brandset.json');

    if (response.status !== 200) {
    KosLog.error('Failed to load beverage data');
    return {};
    }
    const json: BrandsetResponse | null = await response.json();
    const initialBeverages: Record<string, BrandsetIngredient> = {};
    const beverages = json?.ingredients?.reduce((acc, beverage) => {
    acc[beverage.ingredientId] = beverage;
    return acc;
    }, initialBeverages);
    return beverages;
    };
  • Maps data into the AssemblyModel data. Used in cases where the base assembly has been extended with additional properties in the backend. This extension point allows for the data to be mapped into the AssemblyModel and augmented with additional properties.

    Parameters

    • assemblyDataMapper: AssemblyMapper<Record<string, any>, AssemblyResponse<any>>

    Returns DispenseExtensionManager

    Example

    In this example of an implementation of a AssemblyMapper, the AssemblyResponse data is mapped into a FreestyleAssembly object.

    The FreestyleAssemblyResponse interface represents the additional data being returned by the assembly service and is merged into the AssemblyResponse interface.

    The FreestyleAssembly interface represents the additional data, beyond the base data set, that will be merged into the AssemblyModel.

    The mapper is responsible for mapping from the FreestyleAssemblyResponse format to the FreestyleAssembly format.

     import { AssemblyTypes } from "@kosdev-code/kos-dispense-sdk";
    import { DataMapper } from "@kosdev-code/kos-ui-sdk";

    // define the additional data being returned by the assembly service
    export interface FreestyleAssemblyResponse {
    iceAgitator?: {
    name: "iceAgitator";
    path: string;
    };
    }

    // define the additional data structure that will be merged into the assembly model
    export interface FreestyleAssembly {
    iceAgitator: {
    path: string;
    };
    carbAgitator: {
    path: string;
    };
    }


    // define the mapper that will map the data from the service response into the additional data structure
    // that will be merged into the assembly model.
    // In this case the mapper is responsible for mapping from the {@link FreestyleAssemblyResponse} format to the {@link FreestyleAssembly} format.
    export const assemblyDataMapper: DataMapper<
    AssemblyTypes.AssemblyResponse<FreestyleAssemblyResponse>,
    FreestyleAssembly
    > = async (data) => {
    const response = data.assemblies.reduce((acc, assembly) => {
    const agitatorKeys = ["iceAgitator", "carbAgitator"];
    agitatorKeys.forEach((key) => {
    const agitator = assembly[key];
    if (agitator) {
    acc[key] = agitator;
    }
    });

    return acc;
    }, {} as FreestyleAssembly);
    return response;
    };