# 4. Hello World app

In this section we will complete our "Hello World" app and test it on a device.

### An App Consists of a *Data Model* and *Views*

As you've seen in the [What is JourneyApps?](https://docs.journeyapps.com/reference/get-started/readme) page, building an app on JourneyApps involves the customization of two kinds of things:

* [**Data Model**](https://docs.journeyapps.com/reference/get-started/journeyapps-fundamentals/what-is-the-data-model): This describes the data that your app makes use of (in more technical terms: object models with their fields and relationships)
* [**Views**](https://docs.journeyapps.com/reference/get-started/journeyapps-fundamentals/what-are-views): This defines the *layout and logic* for the actual screens in your mobile app.

You will also have learned that customizing these two things are done using straightforward **XML** and **JS**.

In your Hello World app that you just created, you can access the **Data Model** and **Views** from the corresponding workspace in the Workspace Tabs.

![](https://2865107717-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9TCHLR67eLHBOjPvHhud%2Fuploads%2Fgit-blob-a49afea111b0a2d96d2a1fcc11bbb38b8dde237e%2Foxide-app-marked-views-dm.png?alt=media)

Click on the **Views** workspace in the Workspace Tabs to access the views for your Hello World app. You should see something like this.

![](https://2865107717-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9TCHLR67eLHBOjPvHhud%2Fuploads%2Fgit-blob-578779ec0122754fae7176af954f962c24111dbf%2Foxide-app-views.png?alt=media)

On the left of your screen you can see a **Views** panel listing all the views for your app. By default each app will have two views to begin with, one called "main" and one called "nav". The "main" view is the very first view that is rendered when the app is loaded, and the "nav" view is used to manage more advanced navigation (something for a later topic).

Each view is divided into two separate files, a `.xml` file, which is used to describe the layout of the view, and a `.js` file, which is used to describe the business logic for the view. By default, when you open a view to edit it both of these files will be opened for you, the `xml` in the left editor pane and the `js` in the right editor pane. This can be seen in the image above for the "main" view. OXIDE has opened the `xml` in the left editor pane and the `js` in the right editor pane.

### Adding Components to Views

Let's go ahead and add some basic details to our Hello World app. For now we are just going to add some basic components, and we will add them to our "main" view. So, make sure you are on the "Views" workspace (to get here simply click on Views in the Workspace Tabs), then make sure you are on the "main" view (to do this select the "main" view from the Views panel on the left of the workspace).

We are going to add a `heading` and an `info` component to our "main" view `xml` to get us started.

In the "main" view xml, add a new line after `<!-- Components go here: -->` section, then type `head` and you should see something like this ...

![](https://2865107717-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9TCHLR67eLHBOjPvHhud%2Fuploads%2Fgit-blob-ac5be9b920003cc55c8b6de7b1dfe62c07ad446f%2Foxide-app-main-head.png?alt=media)

What you see beneath your cursor is OXIDE's **Auto-Complete** functionality trying to help you. Hit `return`/`enter` to insert the highlighted auto-complete suggestion (in this case there was just one option). Now your code should look something like this ...

![](https://2865107717-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9TCHLR67eLHBOjPvHhud%2Fuploads%2Fgit-blob-11aec1c65cc8f488bb96bf49901dba2d2bf3e98d%2Foxide-app-main-heading.png?alt=media)

You will see that OXIDE has inserted the opening and closing tags for your `heading` component for you. All that is left to do is populate it with some text. Let's add the text 'Hello World' to the inside of the `heading` component. Now your code should look like this ...

```xml
<?xml version="1.0" encoding="UTF-8"?>
<view title="Basic Tutorial">
    <!-- Parameters go here: -->

    <!-- Variables go here: -->

    <!-- Component go here: -->
    <heading>Hello World</heading>
</view>
```

![](https://2865107717-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9TCHLR67eLHBOjPvHhud%2Fuploads%2Fgit-blob-b42f1dbf12401db878e10fde076303d6d4f28c8a%2Foxide-app-main-heading-pop.png?alt=media)

Excellent, now let's do the same for an `info` component. We are going to add the component underneath the `heading` component, we are going to use auto-complete to let OXIDE insert the xml tags for us, and once it is there we are going to populate it with some text, in this case the text 'This is my first app'.

So, start by typing `inf`, then use your arrow keys to highlight the `info` component in the auto-complete suggestions, not the `info-table` component. Once the suggestion is highlighted hit `return`/`enter`, and finally add the text 'This is my first app' inside of the `info` component. Now your code should look like this ...

```xml
<?xml version="1.0" encoding="UTF-8"?>
<view title="Basic Tutorial">
    <!-- Parameters go here: -->

    <!-- Variables go here: -->

    <!-- Component go here: -->
    <heading>Hello World</heading>
    <info>This is my first app</info>
</view>
```

![](https://2865107717-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9TCHLR67eLHBOjPvHhud%2Fuploads%2Fgit-blob-88b1aa51dc889f4f4ccc3b426485e16ae60a9f44%2Foxide-app-main-inf.png?alt=media)

![](https://2865107717-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9TCHLR67eLHBOjPvHhud%2Fuploads%2Fgit-blob-48dcaff8b124c765245321ab11814b74c20f26ee%2Foxide-app-main-info.png?alt=media)

Great, now let's test your app to see what it looks like.

### Testing Your App: Link a Mobile Device or Test on Desktop

An important concept in JourneyApps is that you should test your app continuously while you are building it. Therefore, immediately go to the **Test app** action (bottom right corner of OXIDE) of your Hello World app and follow the instructions to either:

* Install the **JourneyApps Container** from the *Play Store* (Android) or *App Store* (iOS) and link your Hello World app to a mobile device.
* Download and install the [JourneyApps Container](https://appinstall.xyz/journey/latest) for Windows or MacOS and test the app on Desktop.

The very first time you run 'Test app' you will be prompted to create a new app user, this is normal as no app user would exist for you yet. Simply hit `continue` and then you will be presented with instructions on how to test your app.

![](https://2865107717-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9TCHLR67eLHBOjPvHhud%2Fuploads%2Fgit-blob-c032a4d3ef7bd875f4adb283e90f23ac31aa715b%2Foxide-app-test-newuser.png?alt=media)

![](https://2865107717-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9TCHLR67eLHBOjPvHhud%2Fuploads%2Fgit-blob-86a2d053141b6114f8577d280e44283dd3787c5d%2Foxide-app-test.png?alt=media)

Ensure that you have downloaded and installed the [JourneyApps Container](https://appinstall.xyz/journey/latest) for Desktop before proceeding. Once installed, click on the 'Or test on desktop' `button` in the **Test app** action (bottom right corner of OXIDE). If all went well the JourneyApps Container for desktop should launch and look something like this ...

![](https://2865107717-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9TCHLR67eLHBOjPvHhud%2Fuploads%2Fgit-blob-307c465ed6f1da043fb5dd01ebf96a4ebf111f81%2Fdesktop-main-helloworld.png?alt=media)

And if you are also following along on your mobile device, it should look something like this ...

![](https://2865107717-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9TCHLR67eLHBOjPvHhud%2Fuploads%2Fgit-blob-7b0632e2649aedf2eb6d370b6d6078ba0d965882%2Fmobile-main-helloworld.png?alt=media)

### Add an Input Component

Now let's make the app a bit more interactive by adding an input component. We want to complete our Hello World app by making it ask the user to enter their name, and then have a button that will make the app display a greeting when it is pressed.

In a full-blown JourneyApps application, we would use the *Data Model* as we'll show you later, but for now, to keep things really simple, we'll simply use a local variable to store user input. To add a local variable, type `var` on a new line under the `<!-- Variables go here: -->` section in your View XML and hit `return`/`enter` to auto-complete as usual.

```xml
<?xml version="1.0" encoding="UTF-8"?>
<view title="Basic Tutorial">
    <!-- Parameters go here: -->

    <!-- Variables go here: -->
    <var name="" type="" />

    <!-- Component go here: -->
    <heading>Hello World</heading>
    <info>This is my first app</info>
</view>
```

We want to ask the user to enter their name, so type something like *your\_name* for the `name` property, and then *text* for the `type` property. *text* indicates that we'll be storing text in this variable (we'll show you all the different data types later.)

```xml
<?xml version="1.0" encoding="UTF-8"?>
<view title="Basic Tutorial">
    <!-- Parameters go here: -->

    <!-- Variables go here: -->
    <var name="your_name" type="text" />

    <!-- Component go here: -->
    <heading>Hello World</heading>
    <info>This is my first app</info>
</view>
```

**Important:** Note that the order in which you insert XML is important — we will cover each of these in more details later, but your XML needs to be specified in the following order: `parameters`, `variables`, `components`. If you see an error message such as *"Elements must be in this order: parameters, variables, components"* or *"This element is not expected"* , it means that something has been inserted in the incorrect order in the XML.

Next, we need to provide a way for the user to give us their input. In this case we just want to capture some **text** and so a `text-input` component will work well. We want to add a `text-input` component underneath the existing `info` component in the `xml`. So, add a new line after the `info` component and type `text`, highlight the `text-input` auto-complete suggestion and hit `return`/`enter` to insert the component.

By default the `text-input` component has a `bind` attribute and a `required` attribute, but we can specify some additional attributes as well. For now, just add a `label` attribute to the `text-input` component. The `bind` attribute tells the view where to store the input that the end users will enter into the component. `bind` needs to be set to a variable that is declared in the view. The `label` attribute is used to display a text label above the `text-input` component. Let's set the `bind` attribute to the name of the variable we declared, *your\_name*, and the `label` attribute to 'Please enter your name'. Now your code should look like this ...

```xml
<?xml version="1.0" encoding="UTF-8"?>
<view title="Basic Tutorial">
    <!-- Parameters go here: -->

    <!-- Variables go here: -->
    <var name="your_name" type="text" />
    
    <!-- Component go here: -->
    <heading>Hello World</heading>
    <info>This is my first app</info>
    <text-input label="Please enter your name" bind="your_name" required="false" />

</view>
```

![](https://2865107717-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9TCHLR67eLHBOjPvHhud%2Fuploads%2Fgit-blob-9baae18ba2ccb2c1625084ffc0c374398a18f986%2Foxide-app-main-text.png?alt=media)

![](https://2865107717-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9TCHLR67eLHBOjPvHhud%2Fuploads%2Fgit-blob-e2e22139b2e011b9df393dd6c0ebeca983f15867%2Foxide-app-main-text-input.png?alt=media)

![](https://2865107717-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9TCHLR67eLHBOjPvHhud%2Fuploads%2Fgit-blob-9fd9a7daea6dd09dcadb44bcd1d0fee6e0d6d229%2Foxide-app-main-text-label.png?alt=media)

![](https://2865107717-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9TCHLR67eLHBOjPvHhud%2Fuploads%2Fgit-blob-745660f70f718eae77151a95277e0933523d1505%2Foxide-app-main-text-pop.png?alt=media)

And your app should look like the this ...

{% tabs %}
{% tab title="Desktop" %}
![](https://2865107717-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9TCHLR67eLHBOjPvHhud%2Fuploads%2Fgit-blob-ea0bc887e37bf78a0e9bbdc161c9e7ade56c95c3%2Fdesktop-main-entername.png?alt=media)
{% endtab %}

{% tab title="Mobile" %}
![](https://2865107717-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9TCHLR67eLHBOjPvHhud%2Fuploads%2Fgit-blob-18ff7a2a25e36952e16d9291b41daeaf58e5699a%2Fmobile-main-entername.png?alt=media)
{% endtab %}
{% endtabs %}

### Add a Button and Hook It Up With JavaScript

Finally, we are going to add a button, but this time we are going to use the visual editor. Open the command palette (`ctrl+shift+p` / `cmd+shift+p`), then type `design` and select the **Open view in designer** action. When prompted to select a *View Model*, choose the 'main' view. The visual editor should now be open.

![](https://2865107717-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9TCHLR67eLHBOjPvHhud%2Fuploads%2Fgit-blob-6b928fbc41fddb1383058f968630bb658c3a275a%2Foxide-app-main-design.png?alt=media)

![](https://2865107717-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9TCHLR67eLHBOjPvHhud%2Fuploads%2Fgit-blob-3bdc8bdbca1c690e422773c6a1bf069b926de060%2Foxide-app-main-designer-model.png?alt=media)

![](https://2865107717-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9TCHLR67eLHBOjPvHhud%2Fuploads%2Fgit-blob-9a0c671222525d91725995414fe05e03c34b8418%2Foxide-app-main-designer.png?alt=media)

Now, to add a new component using the visual editor, simply click on the **+** underneath the visualization of the `text-input` component, select the `button` component from the list, enter 'Press Me' as the Button Label when prompted and then hit 'Continue'.

![](https://2865107717-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9TCHLR67eLHBOjPvHhud%2Fuploads%2Fgit-blob-58a9947f840757aed30c30a2a12e1be746f4b561%2Foxide-app-main-design-button.png?alt=media)

![](https://2865107717-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9TCHLR67eLHBOjPvHhud%2Fuploads%2Fgit-blob-19109fe07134b115ef23108097344aa08f288bc5%2Foxide-app-main-design-button-label.png?alt=media)

Once added, go back to your main view xml by clicking on 'main' view in the View Panel on the left, this will open the main view xml in the left editor pane and the main view `js` in the right editor pane. Once there, you should see this, the visual editor has added a `button` component for you in the `xml` and also populated some of the xml attributes of the `button` component. You may have also noticed that the visual editor has created a new `js` function for you ...

![](https://2865107717-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9TCHLR67eLHBOjPvHhud%2Fuploads%2Fgit-blob-0ac35a1cc668c48b2f0cf2d56a7d019d007c5108%2Foxide-app-main-design-button-result.png?alt=media)

Next up, let's add the necessary `js` code to return a dialog once the user presses our button. We are going to use a simple `dialog` JS component, and this component takes a string as an argument. Update your JS function to the following ...

```javascript
function buttonPress() {
    // TODO implement
    dialog("Hello there, " + view.your_name);
}
```

![](https://2865107717-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9TCHLR67eLHBOjPvHhud%2Fuploads%2Fgit-blob-46d9f4bc67ca4e50ac98ed2a62bb1e13247dd379%2Foxide-app-main-jsButton.png?alt=media)

All right, let's test it out! Open your app (either desktop or mobile), and see that it now looks and works like this ...

{% tabs %}
{% tab title="Desktop" %}
![](https://2865107717-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9TCHLR67eLHBOjPvHhud%2Fuploads%2Fgit-blob-586c7141429dad0726228d678b6442e28cd58c33%2Fdesktop-main-input.png?alt=media)

![](https://2865107717-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9TCHLR67eLHBOjPvHhud%2Fuploads%2Fgit-blob-c72383eef3dc2a7b8b725a45ef589d7e495a920c%2Fdesktop-main-input-dialog.png?alt=media)
{% endtab %}

{% tab title="Mobile" %}
![](https://2865107717-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9TCHLR67eLHBOjPvHhud%2Fuploads%2Fgit-blob-f1073f3429feb7fc6700e17f44dcf940aa2aeb3a%2Fmobile-main-input.png?alt=media)

![](https://2865107717-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9TCHLR67eLHBOjPvHhud%2Fuploads%2Fgit-blob-fb354618441df8ebf5a2e5e620e5735f460a65e5%2Fmobile-main-input-dialog.png?alt=media)
{% endtab %}
{% endtabs %}

### Hello World DONE!

Excellent, you have successfully completed your first JourneyApps 'Hello World' app. Below you will find the reference code for the 'main' view `xml` and `js` of this 'Hello World' app. If your app is not working like ours, or you broke it and cannot seem to fix it, simply copy and paste both the `xml` and the `js` over to your app and then try again.

{% code title="main.xml" %}

```xml
<?xml version="1.0" encoding="UTF-8"?>
<view title="Basic Tutorial">
    <!-- Parameters go here: -->

    <!-- Variables go here: -->
    <var name="your_name" type="text" />

    <!-- Component go here: -->
    <heading show-if="true" hide-if="false">Hello World</heading>
    <info>This is my first app</info>
    <text-input label="Please enter your name" bind="your_name" required="false" show-if="true" hide-if="false" />
    <button on-press="$:buttonPress()" label="Press Me" />

</view>
```

{% endcode %}

{% code title="main.js" %}

```javascript
// This function is called when the app navigates to this view (using a link)
function init() {
    // initialize any data here that should be available when the view is shown
}

// This function is called when the user returns to this view from another view
function resume(from) {
    // from.back       (true/false) if true, the user pressed the "Back" button to return to this view
    // from.dismissed  (true/false) if true, the app dismissed to return to this view
    // from.path       contains the path of the view that the user returned from
    // if any data needs to be refreshed when the user returns to this view, you can do that here:
}


function buttonPress() {
    // TODO implement
    dialog("Hello there, " + view.your_name);
}
```

{% endcode %}

### Automatic Saving, Deployment & Testing on Mobile Device

Note that whenever you type something into OXIDE, it will automatically be saved. There is no need to save anything explicitly. Furthermore, you may have noticed that every time you make a change, there is a **Deployment** process that gets kicked off, indicated by the progress bar that appears over the **Footer**. This is the OXIDE `auto-deploy` feature and is enabled by default. You can also trigger a deployment manually by hitting `ctrl+s` / `cmd+s` (**Note** you can turn off the `auto-deploy` feature from the command palette, `ctr+shift+p` / `cmd+shift+p`. This is often useful if you have a poor internet connection or when you are working on large blocks of code at a time. If you do turn it off, just remember to hit `ctrl+s` / `cmd+s` to manually deploy your code before trying to test it).

![](https://2865107717-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9TCHLR67eLHBOjPvHhud%2Fuploads%2Fgit-blob-ede5d265fd2d36d0b6c49590d076248169e44cbc%2Foxide-app-main-deployvisor.png?alt=media)

This means that your app is automatically being deployed to the **Testing Environment** (recall the [Environments and Staged Deployment section on the *What is JourneyApps?*](https://docs.journeyapps.com/reference/readme#environments-and-staged-deployment) page) Your app will try to refresh itself automatically on the mobile or desktop device so that you can see the changes you're making (if it doesn't, press the "sync" button at the top right corner of the app).

**What Kind of Device?** All the applications that you develop on JourneyApps will work on iOS, Android, Windows, MacOS and Web right out of the box, without any additional development required. The applications are also responsive right out of the box, which means you can use the application on any form factor, phone, tablet, laptop and desktop. Write once, run everywhere. A list of supported platforms and minimum operating system version can be found [here](https://docs.journeyapps.com/reference/technical/supported-platforms).

**Container App + Over-the-Air Customizations:** As you've seen in the [What is JourneyApps?](https://docs.journeyapps.com/reference/get-started/readme) page, the JourneyApps Container that you install on your mobile or desktop device is simply an empty generic container. Once you link your device to an app, your app customizations are deployed to it over-the-air, and your app is dynamically rendered. This means that deploying new versions of your app to users is extremely easy and happens in an automated way.
