Skip to Content
Technical Articles

Multiplayer SAPUI5 Web Components for React

Introduction

Multiplayer Applications will make you wonder why traditional single client apps are still standard.  In this blog, I’m going to show you how easy it is to create a front-end React Application with SAPUI5 components.  I’ll then build on this to add tables and charts so that the application can interactively share information with other connected users in real time.

Prerequisites:

  • Basic Knowledge of JavaScript

Recommended Knowledge:

  • JavaScript
  • HTML

First though, a few concepts and conventions:

Concepts:

  • React is a single page application framework , more on this later.
  • I am are going to reuse components created by the talented people in the openUI5 group
  • JavaScript has a few different ways of doing things, in this blog I will be using a mixture, I will point out differences as I go.

Conventions:

Jargon – is labelled like this, you don’t have to read it but it will help your understanding if you do.

Important – You need to understand this.

Command – Stuff you need to type is inside the single quotes (not including the single quotes) – that’s type, not copy – you’ll learn more if you type it.

Action – Stuff you need to do, separated by >.  Example – Start > ‘cmd’

Start being an action to press start on the task bar, and then (denoted by > ), type ‘cmd’

Don’t be put off by the jargon in the concepts, this is a walk-through,so let’s dive in:

Action – Install vscode – https://code.visualstudio.com/

Action – Install node.js (the LTS Version recommended for most users) – https://nodejs.org/en/

 

Jargon – node is an open source server environment, which includes a package manager (npm) which means I can use other (really clever) peoples stuff.  All I need to do is install it and then import modules into my application.  When I do this my application takes note of the dependency and makes sure it is always packaged together.

Important – node.js RUNS ON THE SERVER.  A server can be my local laptop or some kind of server in a datacentre or somewhere in the cloud.  Node.js sends the HTML code that I write to your browser, just like any other web server, but you’re in complete control, similar to having a super power.

Important – Along with cool modules which I can use for free, some clever people thought it would be a good idea to provide templates, so I don’t get weighed down with the boring stuff.  This is called Bootstrapping.  I’m going to use a template to bootstrap my new application:

Open a command prompt, PowerShell or Terminal (from this point onward referred to as prompt), on Windows this would be

Start > ‘cmd’

Or

Start > ‘PowerShell’

Change to a local directory (probably best to create a local development directory to hold all my  future awesome apps).  At the prompt:

‘cd \;mkdir localDev; cd localDev’

‘npx create-react-app meaps’

Jargon – create-react-app is a toolchain.  There are various other tools chains for different types of applications here

After a couple of minutes the bootstrap will complete and I will be able to start my new server.  At the prompt:

‘cd meaps’

‘npm start’

Which should launch a development server and a browser with the React logo spinning in the middle.  I can also browse to http://localhost:3000.  If this did not work for you, go back and re read this important stuff.

So with 3 commands i have built a local server, setup a template single page application and got it running in a browser.

I have a prompt still running my development server? However I would like this to run inside vscode.  At the prompt:

Action – Press ‘ctrl c’ and type ‘y’ to Terminate batch job.

‘code .’

code then a space  and then a period.

This will open vscode in the correct directory.  When I refresh my browser I get an error because I cancelled the batch job.  To fix this, in vscode:

Action – Pull down menu > Terminal > New Terminal

Which will display a New Terminal at the bottom of the page, which is now my new prompt.  In the terminal windows title bar > locate:

Action – Left of the trash can > click on the 2 window

 

two%20windows

two windows

This will give me 2 terminals.  In one of the 2 terminals enter:

‘npm start’

And now I can see my react logo spinning again in my browser again.

Let’s have some fun.  In the EXPLORER window, I can see some files and folders, I can edit by double clicking on them:

Action – MEAPS > src > app.js

Action – replace all the cope with:

import React from 'react';
import logo from './logo.svg';
import './App.css';
function App() {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          SAPUI5 Components are lightweight, easy to use and super-fast in loading.
        </p>
        <p>
        Some of the components can be containers for other non UI5 components,
        </p>
        <p>
        There is even a whole category of ui5 react charts
        </p>
        <a
          className="App-link"
          href="https://sap.github.io/ui5-webcomponents-react/?path=/docs/charts-piechart--render-formated-story"
          target="_blank"
          rel="noopener noreferrer"
        >
          Explore React Charts
        </a>
      </header>
    </div>
  );
}
export default App;

 

And save the app.js file press\type:

Cntrl ‘s’

My browser is updated immediately.  Which means I can design as I go.

Next step is to make this a little more SAPUI5 looking, but first a little on the file and folder structure.

Jargon – Files and folder structure,   I’ll be brief; MEAPS is my source (base) folder and holder files that describe (to the package manager NPM) dependencies, and some other run and build parameters.  The important file is package.json, more on this later.  MEAPS\node-modules folder holds all the good stuff other people have coded.  MEAPS\public holds the static files of my application, these files are immutable (cannot change them) acting as resources for node.js to call.  MEAPS\src this is where the magic happens, where the code goes that is run by node when I run npm start.  You really don’t need to know this – I can trace the execution of the npm start command in the package.json > scripts > react-scripts start.  React-scripts is a module in the node_modules folder where I will find react-scripts/scripts/start.js, and if I keep following the code I may find a bucket of gold at either end of the rainbow function…  ok enough of that…

Before I start making things look a little more appealing, I need to restructure the application in order to take advantage of what REACT provides.

Jargon – In order for vscode to syntax check and autocomplete (intellicode) I have to tell it I am as using React by using the file extension .jsx.  I also get the added benefit of the React syntax extension which I will need.  I can also continue to use regular JS components… win win win

Let’s create a new root component for my MEAPS app called Home.jsx:

Action – right click src folder > select New File > ‘Home.jsx’

And just so I have something to look at copy and paste the following code:

import React from "react";
import { useHistory } from "react-router-dom";
export function Home() {
  const history = useHistory();
  return (
      <p>
          Not much to look at
      </p>
  );
}

 

And save the file

Action – ctrl S

I need to change the app.js file to call our new .jsx page but before I do, I will install the ui5 components for React and some other helper module. In the Terminal window at the bottom of vscode:

Action – ‘npm install react-router-dom’

Action – ‘npm install @ui5/webcomponents’

Action – ‘npm install @ui5/webcomponents-react’

Action – ‘npm install @ui5/webcomponents-fiori’

Open the app.js file

Action – MEAPS/app.js

And replace all the code with:

import React from 'react';
import { HashRouter } from "react-router-dom";
import { ThemeProvider } from "@ui5/webcomponents-react/lib/ThemeProvider";
import "@ui5/webcomponents/dist/Assets.js";
import { Home } from "./Home"

function App() {
  return (
    <HashRouter>
      <ThemeProvider>
        <Home />
      </ThemeProvider>
    </HashRouter>
  );
}
export default App;

And save the file

Action – ctrl S

OK so that was a bit of juggling however the logic is simple.  All I have done is configured app.js to load the new components Home.jsx instead of the code which was hardcoded in app.js.  I added a few of helper modules to grease the gears.   Checking my browser I see that there’s “Not much to look at” so I’ll fix that now.

Action – right click src folder > select New File > ‘Home.jsx’

And just so I have something to look at, I can copy and paste the following code:

import React from "react";
import { useHistory } from "react-router-dom";
import { ShellBar, ShellBarItem } from "@ui5/webcomponents-react";
import "@ui5/webcomponents/dist/Assets.js";

export function Home() {
  const history = useHistory();
  const handleLogoClick = () => {
    history.push("./");
  };
  return <>
    <ShellBar 
    logo={<img src="logo192.png" />}
    primaryTitle="MEAPs"
    onLogoClick={handleLogoClick} >
      <ShellBarItem icon="add" text="Add" />
    </ShellBar>
  </>;
}

My browser now looks like this:

titlebar

Now I have a title bar which is a SAPUI5 web component for React.  As I mentioned earlier this is a single page application, so I need a mechanism to dynamically load content.  I can do this with the React Router (the module I added earlier (npm install react-router-dom).  In order to dynamically load content I need another component to load.

Action – right click src folder > select New File > ‘Page1.jsx’

Then copy and paste the following code:

	import React, { Component } from 'react';
	import {
	    Card
	    FlexBox,
	    FlexBoxJustifyContent,
	    FlexBoxWrap,
	    Icon  
	} from "@ui5/webcomponents-react";
	import { spacing } from "@ui5/webcomponents-react-base";
	import "@ui5/webcomponents/dist/Assets.js";
	import { useHistory } from "react-router-dom";
	class Page1 extends Component {
	   
	    render() {
	        return (
	            <FlexBox
	            justifyContent={FlexBoxJustifyContent.Center}
	            wrap={FlexBoxWrap.Wrap} 
	            >
	                <Card 
	                    heading="A UI5 Card"
	                    style={{ width: "300px", ...spacing.sapUiContentPadding }}
	                    avatar={<Icon name="table-view" />}>
	                </Card>
	            </FlexBox>
	        );
	    };
	}
export default Page1;

OK, so there is quite a lot going on, the main difference being that this component is a class whereas the previous components were functions.  There are reasons for using either style which is not important for this walk-through but you can read about here

The important parts are; I have imported some styling components (card, flexbox…) which make it easy to layout the page. Then I have introduced the render() function of Component (because I get render for free when I extend Component).  Notice that in a function component I do not use render().  The render() function is a wrapper for the return() function.  Then I can use mark-up to place the components in the page DOM hierarchy.

Now that I have setup the application framework I will only list new code.

I need to amend the Home.jsx to call the new Page1 by importing the new Page1 and add a Switch component with routes to the pages I have created.

import Page1 from "./Page1.jsx";

and modifying the following lines:

import { useHistory, Switch, Route, Redirect } from "react-router-dom";
return <>
    <ShellBar 
    logo={<img src="logo192.png" />}
    primaryTitle="MEAPs"
    onLogoClick={handleLogoClick} >
      <ShellBarItem icon="add" text="Add" />
    </ShellBar>
    <Switch>
      <Route path="/page1" component={Page1} />
      <Redirect from="/" to="/page1" />
    </Switch>
</>;

 

And in my browser:

meapCard

 

That’s enough for this blog.  In the next blog I’ll be adding a table and getting some data from a remote source.

Conclusion

I have created a SAPUI5 react application and restructured it to dynamically load class components which I have imported.

Call To Action

  • Next step is to add a table which reads a remote data source, look out for my next blog.
  • Let me know your thoughts for:
    • Additional functionality
    • Use cases for full duplex multiplayer applications

 

1 Comment
You must be Logged on to comment or reply to a post.