When creating complex Freestyle SAPUI5 Apps its a good practice to organize the code in the project.
Through extending the sap.ui.model.json.JSONModel you have a clean way to organize specific code that is responsible for managing specific object data. For example, user data that needs to be read once can be outsourced to a user model. The data can then be read directly once in the Component.js.
Now… what if we need to send a request in the object page in the method _onObjectMatched that requires data from the user model as a parameter? How can we wait for the data to be loaded in the user model?
Guess what – This code snippet shows a possible solution using the Promise object.
User.ts
import ODataModel from "sap/ui/model/odata/v2/ODataModel";
import Component from "sap/ui/core/UIComponent";
import JSONModel from "sap/ui/model/json/JSONModel";
export default class User extends JSONModel {
private serviceModel: ODataModel
public userDataLoaded: Promise<void>
private resolveUserDataLoaded: Function
public constructor(component: Component) {
super({
busy: true,
data: {
Pernr: undefined
}
});
this.serviceModel = <ODataModel>component.getModel();
this.userDataLoaded = new Promise((resolve) => { this.resolveUserDataLoaded = resolve });
}
public async readData(key: string) {
this.setProperty("/busy", true);
try {
await this.serviceModel.metadataLoaded();
let readResponse = await this._read(key);
this.setProperty("/data", readResponse);
this.resolveUserDataLoaded();
} catch (error) {
throw error;
} finally {
this.setProperty("/busy", false);
}
}
private _read(key: string): Promise<void> {
const serviceModel = this.serviceModel;
return new Promise((resolve, reject) => {
const path = serviceModel.createKey("/UserSet", {
Pernr: key
});
const parameters = {
success: resolve,
error: reject
};
serviceModel.read(path, parameters);
})
}
}
models.ts
import Component from "../Component";
import User from "./User";
export function createUserModel(component: Component): User {
const model = new User(component);
model.setDefaultBindingMode("OneWay");
return model;
}
Component.ts
import { createUserModel } from "./model/models";
import User from "./model/User";
//set the user model
this.setModel(createUserModel(this), "user");
(<User>this.getModel("user"))?.readData("99999999");
Object.controller.ts
private async onObjectMatched(evt: Route$PatternMatchedEvent): Promise<void> {
const parameter = (<any>evt.getParameter("arguments"));
//wait for user data being loaded
//this.viewModel.setProperty("/busy", true);
await (<User>this.getModel("user"))?.userDataLoaded;
//this.viewModel.setProperty("/busy", false);
//TODO: read data with information from the userModel
}
Related Information
💡 For more tips on how to organize your code check out the following blog post: How to organize your code in your SAPUI5 project
