DEV Community

Kevin Jump
Kevin Jump

Posted on • Edited on

Early Adopter's Guide to Umbraco v14 Packages : Communicating with the server! - Part 3 - Context

The code for this series of posts can be viewed here : https://github.com/KevinJump/TimeDashboard

4. Context.

Coming from a Umbraco v13, AngularJs world; Its proribly best to think of the context as the 'service' element - it handles all the code from your controllers (LitElements mostly), does some logic, passes things two and from the repositories and it can do a little state management if you want it to (although maybe thats what the store is for??).

Context's are handled slightly diffrently than repositories and stores, because you want them to have some context for umbraco and the application, which they can then pass on.

You can instanciate contexts a couple of way's here we are going to make a 'globalContext' simply because we haven't yet talked about workspaces, and elements, and its the simpest to define.

A global context can be defined like so:

const contexts : Array<ManifestGlobalContext> = [
    {
        type: 'globalContext',
        alias: 'time.context',
        name: 'Time context',
        js: () => import('./time.context.ts')
    }
]
Enter fullscreen mode Exit fullscreen mode

(we wrap this array into our entry point lower down in our code)

Our "time context" is a little longer than before but we will step though it.

Setup

First we have to get our context setup:

export class TimeManagementContext extends UmbControllerBase {

    #repository: TimeManagementRespository;

    constructor(host: UmbControllerHost) {
        super(host);

        this.provideContext(TIME_MANAGEMENT_CONTEXT_TOKEN, this);
        this.#repository = new TimeManagementRespository(this);

        this.consumeContext(UMB_AUTH_CONTEXT, (_auth) => {
            const umbOpenApi = _auth.getOpenApiConfiguration();
            OpenAPI.TOKEN = umbOpenApi.token;
            OpenAPI.BASE = umbOpenApi.base;
            OpenAPI.WITH_CREDENTIALS = umbOpenApi.withCredentials;
        });
    }
Enter fullscreen mode Exit fullscreen mode

The key things here, are:

  1. ProvideContext there are some comments in the core code that you shouldn't self provide the context, but then its done all over the place, and it works. A context must be provided somewhere, with a token, this is how other elements then consume it and all share the context.

  2. Auth Context : Now this took ages to dig out.

When you generate your Api (from the openapi cli tool) - the client will generate all the code and config you need to communicate with the sever. but it wont have the authentication token.

Umbraco does have this token set for its own config/calls, so we have to go get it and set it on our calls for them to correctly call the server. miss this step and authentication will not work for you

🚨 So to repeat - because its worth repeating 🚨

make sure you set the OpenAPI values for your openAPI
config or authentication will seem to be a mystery to you.

this.consumeContext(UMB_AUTH_CONTEXT, (_auth) => {
   const umbOpenApi = _auth.getOpenApiConfiguration();
   OpenAPI.TOKEN = umbOpenApi.token;
   OpenAPI.BASE = umbOpenApi.base;
   OpenAPI.WITH_CREDENTIALS = umbOpenApi.withCredentials;
});

properties

Now we are going to give out context some properties, and introduce 'observables' which are just things you can watch for changes.

#time = new UmbStringState("unknown");
public readonly time = this.#time.asObservable();

#date = new UmbStringState("unknown");
public readonly date = this.#date.asObservable();
Enter fullscreen mode Exit fullscreen mode

methods

Here we are going to set the methods, these are very close to being the things we are going to call when someone clicks something!.

These methods call the repository (which calls the store, which calls the resources, which calls the serever). and returns the data.

async getTime() {
    const {data} = await this.#repository.getTime();

    if (data) {
        this.#time.setValue(data);
    }
}

async getDate() {
    const {data} = await this.#repository.getDate();

    if (data) {
        this.#date.setValue(data);
    }
}
Enter fullscreen mode Exit fullscreen mode

Export and define

Finally we export and define out context.

export default TimeManagementContext;

export const TIME_MANAGEMENT_CONTEXT_TOKEN =
    new UmbContextToken<TimeManagementContext>
            (TimeManagementContext.name);
Enter fullscreen mode Exit fullscreen mode

The token is important in other elements finding your context;

Exporting it as default means you can do the js: ()=> import line in the manifest, and when all the code is bundles references are included.

Next . A Button !!!


Updated: 2/3/2024: preview008. UmbBaseController -> UmbControllerBase

Top comments (0)