Skip to content

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.

FileResponsibilityInspect this now
package.jsonnpm commands and tooling dependenciesFind scripts.start and scripts.build.
package-lock.jsonExact installed dependency versionsKeep it in Git; use npm ci to reproduce the install.
ui5.yamlDevelopment server configurationFind SAPUI5 version 1.148.12 in the proxy configuration.
webapp/Component.jsApplication component initializationFind UIComponent, manifest: "json" and init.
webapp/manifest.jsonApp identity and UI5 configurationFind sap.app.id, libraries, models and root View.
webapp/view/App.view.xmlGenerated outer shellFind the App control with local ID app.
webapp/view/Main.view.xmlThe screen you are editingFind the button and .onSayHello.
webapp/controller/Main.controller.jsScreen behaviorFind onSayHello.
webapp/i18n/i18n.propertiesGenerated app title/description textsRecognize 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:

DependencyParameter
sap/ui/core/mvc/ControllerController
sap/m/MessageToastMessageToast
training/fiori/day1/util/GreetingGreeting

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 ​

  1. Temporarily change the Greeting dependency path from util/Greeting to utils/Greeting.
  2. Save, reload, and inspect Console and Network in DevTools. Locate the failed module request.
  3. Restore util/Greeting and 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 status

If Git reports that this is not a repository, initialize it:

bash
git init

Open .gitignore. The generated file already contains useful exclusions. Preserve them and ensure these entries are present:

text
node_modules/
dist/
.env

Keep 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 status

git 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 ​

  1. Select Say Hello and confirm the updated greeting.
  2. Confirm that only the Controller imports MessageToast; Greeting simply returns text.
  3. Verify that the deliberate broken path was restored.
  4. Run git log -1 --oneline and check that your commit is recorded.
  5. Confirm git status is 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 ​

SymptomLikely causeWhat to do
Greeting module returns 404Incorrect folder, case or module pathCheck webapp/util/Greeting.js and the exact slash-based dependency.
Greeting.buildGreeting failsDependency/parameter order mismatchCompare each dependency with the parameter in the same position.
Manifest fails to parseInvalid JSON editRemove comments/trailing commas; restore the checkpoint if needed.
Git refuses a commitMissing identity or nothing stagedRead the message; use the local identity commands or stage intended changes.
Dependencies appear in GitMissing ignore rule or files already trackedAdd the ignore rule and untrack the staged dependency folder without deleting it.

6. Check your understanding ​

  1. Why put buildGreeting in its own module?
  2. What is the relationship between a dependency and a callback parameter?
  3. Which file defines the application ID?
  4. Does git commit upload your code?
Suggested answers
  1. It separates reusable logic from screen interaction and can be called/tested independently.
  2. UI5 passes the loaded modules to the callback in the dependency array's order.
  3. webapp/manifest.json, under sap.app.id.
  4. 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.

Independent learning materials for SAP frontend development.