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