Skip to content

BryceEWatson/tesko

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

44 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

marlow

A collection of tools to help you build in the marko-js, marko widget, and lasso stack.

For more information please visit the following resources:

installation

$ git clone git@github.com:bryceewatson/marlow
$ cd marlow && npm link

usage

To open the web ui (Note: web ui is still in progress)

$ marlow

To generate a new project

$ marlow --generate my-project

To generate and start a new project

$ marlow --generate my-project --start

getting started

This guide will help you learn the marko-js, marko-widget, and lasso stack. By the end you will have a Space Station Tracker website which updates its latitude and longitude from the Open API Endpoint.

  1. Get marlow:
$ git clone git@github.com:bryceewatson/marlow
$ cd marlow && npm link
  1. Create your project:

    $ marlow --generate space-station-tracker --start

You should see the default hello-marko project in your browser. Don't worry, we will be modifying this project into a space station tracker.

  1. Let's build our first marko widget. In the space-station-tracker folder, navigate to the src/components folder and create a new component for our station-station-tracker app. The easiest way is to copy an existing widget:
$ cd space-station-tracker/src/components
$ cp app-hello-message app-location-display
$ cd app-location-display

Click here to learn more about marko widgets.

  1. We will start by modifying the template.marko file. Replace the existing code in this file to:
<section id="app-location-display" w-bind>
    <div>${data.lat}, ${data.lng}</div>
</section>
  1. Now, modify the marko-tag.json file to define the data object's properties:
{
  "@lat": "string",
  "@lng": "sting"
}
  1. In index.js, we need to define the widget state variables. In the getInitialState function, change name: input.name, to lat: input.lat, and welcomeMsg: input.welcomeMsg to lng: input.lng.

  2. Similarly, in getTemplateData, change name: state.name to lat: state.lat and welcomeMsg: state.welcomeMsg to lng: state.lng.

  3. Congratulations, you've created your first marko widget! Now, let's add some data. For our project, Rwe're going to be using the "Open Notify" API to get the current location of the International Space Station.

  4. In the Copy the hello folder into a location folder:

$ cd space-station-tracker/src/services
$ cp hello location
  1. In the location folder, modify the routes.js file's module.exports object to point to our new location endpoint. We will be defining the getLocation method shortly:

    module.exports = {
        name: 'getLocation',
        method: 'GET',
        path '/api/getLocation'
    }
  2. In handlers.js, replace all of the code with the following:

var http = require('http');

module.exports = {
    getLocation: function (args, callback) {
        http.get('http://api.open-notify.org/iss-now.json', (res) => {
            var body = '';
            res.on('data', function(chunk){
                body += chunk;
            });
            res.on('end', function(){
                callback(null, {
                    location: JSON.parse(body)
                });
            });
        }).on('error', (e)=> {
            console.log('Error getting location: ${e.message}');
        });
    }
};
  1. Now that we've defined the service, let's connect it to our application. In src/app/App.js, replace
var helloService = require('src/services/hello');

with

var locationService = require('src/services/location');
  1. Next, within the App.prototype object, replace the getWelcomeMsg function with the following code:
getLocation: function() {
    var self = this;
    this.serverSyncPromise = new Promise(function(resolve, reject){
        locationService.getLocation({}, function(err,data){
            if(err){
                return reject(err);
            }
            var location = {
                lat: parseFloat(data.location.iss_position.latitude).toPrecision(5),
                lng: parseFloat(data.location.iss_position.longitude).toPrecision(5)
            };
            self.state.set('location', location); //emits an app state change event
            resolve();
        });
    });
    return this.initialServerSyncPromise;
},

Whenever App.getLocation is called, the locationService is called, and the response is used to update the state object.

  1. In AppState.js, let's initialize the AppState method and set our default values. Replace
this.name = state.name || 'World';
this.welcomeMsg = state.welcomeMsg || null;

with

this.location = state.location || {lat: 0, lng: 0};

When AppState's set method is called, a change event is triggered, which causes the widgets to be rerendered. We will see how the widgets are rerendered next.

  1. In the root directory's index.js file, replace
require('./src/services/hello').addRoutes(app);

with

require('./src/services/location').addRoutes(app);
  1. Now that our service is in place, let's connect it to the marko widgets. The main app widget (located in components/app) subscribes to this change event and receives the location data. Replace the existing getTemplateData method to the following:
getTemplateData: function(state, input){
    var location = state.location;
    return {
        location: location
    };
},

This sends our location object to the widget template in components/app .

  1. In components/app/template.marko, replace the existing element with:
<app-main location=data.location />

This passes the location to the app-main widget.

  1. In app-main, replace the existing and elements with:
<app-location-display lat=data.location.lat lng=data.loation.lng />

This passes the latitude and longitude to our app-location-display widget.

  1. Before we go to our app-location-display widget, we need to change the object in marko-tag.json to:
{
  "@location": "expression"
}
  1. You may be wondering why we pass the location data through multiple layers of widgets. In a larger application, a main app widget could be used to manage multiple UI components and associated data. In app-main's index.js file, modify the getInitialState method to return:
{
  location: input.location
}
  1. Modify the getTemplateData method to return:
{
  location: state.location
}
  1. Now, run the application by entering npm start in the terminal. In your browser and go to localhost:8080. You should see 0, 0 since these are our default coordinates. Next, we will call our service at regular intervals to display location data dynamically.

  2. In app-location-display/index.js, let's override the init method.

init: function(){
    setInterval(function(){
        app.getLocation();
    }, 3000);
}

Finally, we can update our app-location-display widget to render the latitude and longitude to the page:

  1. [Optional] Let's put the finishing touches on our application. In components/app-header, change the text within the <h1> tags to "International Space Station Location Tracker".

  2. [Optional] To make our font look "spacey,", go to src/pages/home/template.marko and add the font style:

<link href="https://fonts.googleapis.com/css?family=Orbitron" rel="stylesheet" type="text/css">

In app-location-display, create a style.less file:

#app-location-display {
    font-family: 'Orbitron', sans-serif;
    background-color: black,
    color: lightgreen;
    display: inline-block;
}

In components/app-location-display, add a file called browser.js with the following code:

{
  "dependencies": [
    "style.less"
  ]
}
  1. [Optional] Since we do not need the app-hello-message and app-live-textbox components, we can delete these from the components folder.

About

A collection of tools to help you build in the marko-js, marko widget, and lasso stack.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published