Appearance
Lesson 2 — Project structure, MVC, modules and Git
Review the companion · Assignment
Continue your Lesson 1 application. You will connect the project files to their responsibilities, create a reusable JavaScript module, and record your work in Git.
1. Start here
Environment: local. Business data/backend: none.
Start with your completed Lesson 1 folder or download the Lesson 1 checkpoint. For a downloaded copy, run npm ci once, then npm start. Use the same training.fiori.day1 application ID throughout these lessons.
Starting check: Say Hello displays Hello from SAPUI5!. Stop and recover that behavior before making structural changes.
2. Understand the idea
MVC means Model–View–Controller. The View describes the interface, the Controller responds to interactions, and a Model holds or exposes data. The model arrives in Lesson 4; this lesson's greeting is still computed from a literal string.
| File | Responsibility | Inspect this now |
|---|---|---|
package.json | npm commands and tooling dependencies | Find scripts.start and scripts.build. |
package-lock.json | Exact installed dependency versions | Keep it in Git; use npm ci to reproduce the install. |
ui5.yaml | Development server configuration | Find SAPUI5 version 1.148.12 in the proxy configuration. |
webapp/Component.js | Application component initialization | Find UIComponent, manifest: "json" and init. |
webapp/manifest.json | App identity and UI5 configuration | Find sap.app.id, libraries, models and root View. |
webapp/view/App.view.xml | Generated outer shell | Find the App control with local ID app. |
webapp/view/Main.view.xml | The screen you are editing | Find the button and .onSayHello. |
webapp/controller/Main.controller.js | Screen behavior | Find onSayHello. |
webapp/i18n/i18n.properties | Generated app title/description texts | Recognize the file; you will learn i18n in Lesson 9. |
The generated Component already sets a device model and starts a default route to Main. Keep that scaffolding. You are not implementing navigation in this lesson; routing is explained in Lesson 8.
In the manifest, sap.app describes the application; sap.ui describes UI technology/device support; sap.ui5 contains framework-specific dependencies, models and views. Declaring phone support does not automatically make every layout usable on a phone; you still need to test the layout.
A namespace identifies your app's modules. The dotted controller class name training.fiori.day1.controller.Main corresponds to the module path training/fiori/day1/controller/Main.controller. The application resource root maps training/fiori/day1 to webapp, not to physical nested folders named training/fiori/day1.
3. Build it
A. Create a reusable module
Create a util folder inside webapp, then create Greeting.js. File names are case-sensitive on many systems.
webapp/util/Greeting.js — complete file
javascript
sap.ui.define([], function () {
"use strict";
return {
buildGreeting: function (sName) {
return "Hello, " + sName + "!";
}
};
});The module returns an object with one function. sName is a string parameter; buildGreeting("Anna") returns Hello, Anna!. It does not display anything itself. This separation makes the function reusable and easy to test later.
B. Import the module in the Controller
Replace the entire Main Controller with this version. The View stays exactly as it was in Lesson 1.
webapp/controller/Main.controller.js — complete file
javascript
sap.ui.define([
"sap/ui/core/mvc/Controller",
"sap/m/MessageToast",
"training/fiori/day1/util/Greeting"
], function (Controller, MessageToast, Greeting) {
"use strict";
return Controller.extend("training.fiori.day1.controller.Main", {
onSayHello: function () {
const sMessage = Greeting.buildGreeting("SAPUI5 Developer");
MessageToast.show(sMessage);
}
});
});The dependency array and callback parameters match by position:
| Dependency | Parameter |
|---|---|
sap/ui/core/mvc/Controller | Controller |
sap/m/MessageToast | MessageToast |
training/fiori/day1/util/Greeting | Greeting |
Module dependencies use slashes and omit .js. Controller.extend names the controller class using dots. Neither notation is the browser DOM ID.
Check: select Say Hello. The toast now says Hello, SAPUI5 Developer!.
C. Practice a controlled debugging change
- Temporarily change the Greeting dependency path from
util/Greetingtoutils/Greeting. - Save, reload, and inspect Console and Network in DevTools. Locate the failed module request.
- Restore
util/Greetingand verify the button again.
Do not leave the deliberate error in your final checkpoint. When a page stops loading, start with the first failed module/request rather than changing unrelated controls.
D. Create a clean Git checkpoint
Open a second terminal in the project root. The first terminal may keep the server running.
bash
git statusIf Git reports that this is not a repository, initialize it:
bash
git initOpen .gitignore. The generated file already contains useful exclusions. Preserve them and ensure these entries are present:
text
node_modules/
dist/
.envKeep package-lock.json tracked. Do not commit credentials or downloaded dependencies. If Git asks for your identity, set it for this repository, using your own values:
bash
git config user.name "Your Name"
git config user.email "your.email@example.com"Inspect, stage, inspect the staged files, then commit:
bash
git status --short
git diff
git add .
git diff --staged --stat
git diff --staged
git commit -m "Add reusable greeting module"
git statusgit diff shows modifications to tracked files; newly created files appear in git status and in the staged diff after git add. If node_modules appears in the staged list, unstage it with git rm -r --cached node_modules, correct .gitignore, and inspect again before committing.
A save updates your working file. Staging selects changes for a commit. A commit records a recoverable version of the project. It does not upload the project to a remote repository.
Changed files: webapp/util/Greeting.js, webapp/controller/Main.controller.js; .gitignore only if an exclusion needed adding.
4. Verify your result
- Select Say Hello and confirm the updated greeting.
- Confirm that only the Controller imports MessageToast; Greeting simply returns text.
- Verify that the deliberate broken path was restored.
- Run
git log -1 --onelineand check that your commit is recorded. - Confirm
git statusis clean after saving and committing all intended changes.
Expected screen: the Lesson 1 layout is unchanged; the button now produces the greeting built by the custom module.
Completed Lesson 2 checkpoint. The download contains source files, not your personal Git history; make your own commit.
5. Troubleshoot
| Symptom | Likely cause | What to do |
|---|---|---|
| Greeting module returns 404 | Incorrect folder, case or module path | Check webapp/util/Greeting.js and the exact slash-based dependency. |
Greeting.buildGreeting fails | Dependency/parameter order mismatch | Compare each dependency with the parameter in the same position. |
| Manifest fails to parse | Invalid JSON edit | Remove comments/trailing commas; restore the checkpoint if needed. |
| Git refuses a commit | Missing identity or nothing staged | Read the message; use the local identity commands or stage intended changes. |
| Dependencies appear in Git | Missing ignore rule or files already tracked | Add the ignore rule and untrack the staged dependency folder without deleting it. |
6. Check your understanding
- Why put
buildGreetingin its own module? - What is the relationship between a dependency and a callback parameter?
- Which file defines the application ID?
- Does
git commitupload your code?
Suggested answers
- It separates reusable logic from screen interaction and can be called/tested independently.
- UI5 passes the loaded modules to the callback in the dependency array's order.
webapp/manifest.json, undersap.app.id.- No. A commit records local repository history; sending it to a remote repository is a separate operation.
7. Continue to Lesson 3
Keep the same project. Lesson 3 replaces the Hello screen with an Employee Profile form. The Greeting module remains as a reusable example, but the new controller will not import it. Open Lesson 3.
8. Official references
Use the SAPUI5 version selector to read the API for 1.148.12, the version used by these checkpoints. Documentation checked on 15 November 2026.