Blog

SOCKET.IO en NODE.JS

Get Started: Chat application

In this guide we’ll create a basic chat application. It requires almost no basic prior knowledge of Node.JS or Socket.IO, so it’s ideal for users of all knowledge levels.

Introduction

Writing a chat application with popular web applications stacks like LAMP (PHP) has traditionally been very hard. It involves polling the server for changes, keeping track of timestamps, and it’s a lot slower than it should be.

Sockets have traditionally been the solution around which most realtime chat systems are architected, providing a bi-directional communication channel between a client and a server.

This means that the server can push messages to clients. Whenever you write a chat message, the idea is that the server will get it and push it to all other connected clients.

The web framework

The first goal is to setup a simple HTML webpage that serves out a form and a list of messages. We’re going to use the Node.JS web framework express to this end. Make sure Node.JS is installed.

First let’s create a package.json manifest file that describes our project. I recommend you place it in a dedicated empty directory (I’ll call mine chat-example).

{
  "name": "socket-chat-example",
  "version": "0.0.1",
  "description": "my first socket.io app",
  "dependencies": {}
}

Now, in order to easily populate the dependencies with the things we need, we’ll use npm install --save:

npm install --save express@4.10.2

Now that express is installed we can create an index.js file that will setup our application.

var app = require('express')();
var http = require('http').Server(app);

app.get('/', function(req, res){
  res.send('<h1>Hello world</h1>');
});

http.listen(3000, function(){
  console.log('listening on *:3000');
});

This translates into the following:

  1. Express initializes app to be a function handler that you can supply to an HTTP server (as seen in line 2).
  2. We define a route handler / that gets called when we hit our website home.
  3. We make the http server listen on port 3000.

If you run node index.js you should see the following:

And if you point your browser to http://localhost:3000:

Serving HTML

So far in index.js we’re calling res.send and pass it a HTML string. Our code would look very confusing if we just placed our entire application’s HTML there. Instead, we’re going to create a index.html file and serve it.

Let’s refactor our route handler to use sendFile instead:

app.get('/', function(req, res){
  res.sendFile(__dirname + '/index.html');
});

And populate index.html with the following:

<!doctype html>
<html>
  <head>
    <title>Socket.IO chat</title>
    <style>
      * { margin: 0; padding: 0; box-sizing: border-box; }
      body { font: 13px Helvetica, Arial; }
      form { background: #000; padding: 3px; position: fixed; bottom: 0; width: 100%; }
      form input { border: 0; padding: 10px; width: 90%; margin-right: .5%; }
      form button { width: 9%; background: rgb(130, 224, 255); border: none; padding: 10px; }
      #messages { list-style-type: none; margin: 0; padding: 0; }
      #messages li { padding: 5px 10px; }
      #messages li:nth-child(odd) { background: #eee; }
    </style>
  </head>
  <body>
    <ul id="messages"></ul>
    <form action="">
      <input id="m" autocomplete="off" /><button>Send</button>
    </form>
  </body>
</html>

If you restart the process (by hitting Control+C and running node index again) and refresh the page it should look like this:

Integrating Socket.IO

Socket.IO is composed of two parts:

  • A server that integrates with (or mounts on) the Node.JS HTTP Server: socket.io
  • A client library that loads on the browser side: socket.io-client

During development, socket.io serves the client automatically for us, as we’ll see, so for now we only have to install one module:

npm install --save socket.io

That will install the module and add the dependency to package.json. Now let’s edit index.js to add it:

var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);

app.get('/', function(req, res){
  res.sendfile('index.html');
});

io.on('connection', function(socket){
  console.log('a user connected');
});

http.listen(3000, function(){
  console.log('listening on *:3000');
});

Notice that I initialize a new instance of socket.io by passing the http (the HTTP server) object. Then I listen on the connection event for incoming sockets, and I log it to the console.

Now in index.html I add the following snippet before the </body>:

<script src="/socket.io/socket.io.js"></script>
<script>
  var socket = io();
</script>

That’s all it takes to load the socket.io-client, which exposes a io global, and then connect.

Notice that I’m not specifying any URL when I call io(), since it defaults to trying to connect to the host that serves the page.

If you now reload the server and the website you should see the console print “a user connected”.
Try opening several tabs, and you’ll see several messages:

Each socket also fires a special disconnect event:

io.on('connection', function(socket){
  console.log('a user connected');
  socket.on('disconnect', function(){
    console.log('user disconnected');
  });
});

Then if you refresh a tab several times you can see it in action:

Emitting events

The main idea behind Socket.IO is that you can send and receive any events you want, with any data you want. Any objects that can be encoded as JSON will do, and binary data is supported too.

Let’s make it so that when the user types in a message, the server gets it as a chat message event. The scripts section in index.html should now look as follows:

<script src="/socket.io/socket.io.js"></script>
<script src="http://code.jquery.com/jquery-1.11.1.js"></script>
<script>
  var socket = io();
  $('form').submit(function(){
    socket.emit('chat message', $('#m').val());
    $('#m').val('');
    return false;
  });
</script>

And in index.js we print out the chat message event:

io.on('connection', function(socket){
  socket.on('chat message', function(msg){
    console.log('message: ' + msg);
  });
});

The result should be like the following video:

Broadcasting

The next goal is for us to emit the event from the server to the rest of the users.

In order to send an event to everyone, Socket.IO gives us the io.emit:

io.emit('some event', { for: 'everyone' });

If you want to send a message to everyone except for a certain socket, we have the broadcast flag:

io.on('connection', function(socket){
  socket.broadcast.emit('hi');
});

In this case, for the sake of simplicity we’ll send the message to everyone, including the sender.

io.on('connection', function(socket){
  socket.on('chat message', function(msg){
    io.emit('chat message', msg);
  });
});

And on the client side when we capture a chat message event we’ll include it in the page. The total client-side JavaScript code now amounts to:

<script>
  var socket = io();
  $('form').submit(function(){
    socket.emit('chat message', $('#m').val());
    $('#m').val('');
    return false;
  });
  socket.on('chat message', function(msg){
    $('#messages').append($('<li>').text(msg));
  });
</script>

And that completes our chat application, in about 20 lines of code! This is what it looks like:

Homework

Here are some ideas to improve the application:

  • Broadcast a message to connected users when someone connects or disconnects
  • Add support for nicknames
  • Don’t send the same message to the user that sent it himself. Instead, append the message directly as soon as he presses enter.
  • Add “{user} is typing” functionality
  • Show who’s online
  • Add private messaging
  • Share your improvements!

Getting this example

You can find it on GitHub here.

$ git clone https://github.com/guille/chat-example.git

Key, Mouse en MouseMotion Events in Java Swing

Key events, mouse events en mouseDragEvents

Voor de cursus object georiënteerd programmeren in Java 2 kom ik veel opdrachten tegen die soms wel leuk zijn om te vermelden. In het gedeelte van de cursus waar de GUI wordt behandeld zitten veel oefeningen met event handling. In dit voorbeeld laat ik de implementatie zien van een frame waar random vierkanten worden gegenereerd die je kunt verslepen met de muis.

Ik heb in dit voorbeeld een klasse Vierkant en een klasse VierkantFrame, de eventhandling van de vierkanten heb ik in de vierkanten zelf opgenomen. Onder staat de implementatie van de klasse Vierkant die over 3 binnenklassen beschikt.

  • implementatie van MouseListener
  • implementatie van MouseMotionListener
  • implementatie van KeyListener
Ik had in dit voorbeeld ook de adapterklassen kunnen gebruiken maak deze implementatie voldoet ook aan het gewenste resultaat.
import java.awt.Color;
import java.awt.Point;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

import javax.swing.JPanel;

/**
 * Representeert een vierkante panel.
 * @author Open Universiteit Nederland
 */
public class Vierkant extends JPanel {
  private static final int AFMETING = 40;
  private static final int DELTA = 10; // verplaatsing in pixels
  private Point anker = null;
  
  /**
   * Maakt een vierkante panel.
   */
  public Vierkant(Color kleur) {
    setSize(AFMETING, AFMETING);
    setBackground(kleur);  
    setFocusable(true);
    //de eventluisteraars worden hier aan het vierkant toegevoegd
    addKeyListener(new PijlLuisteraar());
    addMouseListener(new Muis());
    addMouseMotionListener( new MuisSleper());
    isFocusable();
    requestFocusInWindow();
  }
  
  public class Muis implements MouseListener {

    @Override
    public void mouseClicked(MouseEvent arg0) { }

    @Override
    public void mouseEntered(MouseEvent arg0) { }

    @Override
    public void mouseExited(MouseEvent arg0) { }

    @Override
    public void mousePressed(MouseEvent e) {
      Vierkant.this.requestFocusInWindow();
      Vierkant.this.setBackground(Color.RED);
      anker = new Point(e.getX(), e.getY());
      System.out.println("vierkant geselecteerd met de muis");
      
    }

    @Override
    public void mouseReleased(MouseEvent arg0) { }
    
  }
  
  public class MuisSleper implements MouseMotionListener {

    @Override
    public void mouseDragged(MouseEvent e) {
      System.out.println("X: " + e.getX() + " Y : " + e.getY());
      System.out.println(anker.x + " : " + anker.y);
      int dx = e.getX() - anker.x;
      int dy = e.getY() - anker.y;
      Point oudeLocatie = getLocation();
      Vierkant.this.setLocation(oudeLocatie.x + dx, oudeLocatie.y + dy);
    }

    @Override
    public void mouseMoved(MouseEvent arg0) { }
    
  }
  
  // De pijlluisteraar vangt de 4 pijltjestoetsen af en de letters b, g, r en z om het vierkant waar de focus op is een kleur te kunnen geven.
  public class PijlLuisteraar implements KeyListener {
    
    @Override
    public void keyPressed(KeyEvent key) {
      int toetsCode = key.getKeyCode();
      
      switch(toetsCode) {
        //plaats het vierkant naar links als daar ruimte voor is.
        case KeyEvent.VK_LEFT: System.out.println("pijl links");
            if(getX() - DELTA > Vierkant.this.getParent().getX()) {
              setLocation(getX() - DELTA, getY());
              System.out.println(getX());
            } else{
              setLocation(0, getY());
            }
        break;
        
      //plaats het vierkant naar rechts als daar ruimte voor is.
        case KeyEvent.VK_RIGHT: System.out.println("pijl rechts");
          if((Vierkant.this.getX() + DELTA) + getWidth() < Vierkant.this.getParent().getWidth()) { setLocation(getX() + DELTA, getY()); } else{ setLocation(Vierkant.this.getParent().getWidth() - getWidth(), getY()); } break; //plaats het vierkant naar boven als daar ruimte voor is. case KeyEvent.VK_UP: System.out.println("pijl omhoog"); if((Vierkant.this.getY() - DELTA) > 0) {
            setLocation(getX(), getY() - DELTA);
          } else{
            setLocation(getX(), 0);
          }
        break;
        
      //plaats het vierkant naar beneden als daar ruimte voor is.
        case KeyEvent.VK_DOWN: System.out.println("pijl omhoog");
          if((Vierkant.this.getY() + DELTA + getHeight()) < Vierkant.this.getParent().getHeight()) {
            setLocation(getX(), getY() + DELTA);
          } else{
            setLocation(getX(), Vierkant.this.getParent().getHeight() - getHeight());
          }
        break;
        
        //geef het geselecteerde vierkant een achtergrondkleur bij het intypen van één van de onderstaande toetsen
        case KeyEvent.VK_B: System.out.println("toets b");
            setBackground(Color.BLUE);
        break;
        case KeyEvent.VK_G: System.out.println("toets g");
            setBackground(Color.GREEN);
        break;
        case KeyEvent.VK_R: System.out.println("toets r");
            setBackground(Color.RED);
        break;
        case KeyEvent.VK_Z: System.out.println("toets z");
            setBackground(Color.BLACK);      
        break;
      }
    }

    @Override
    public void keyReleased(KeyEvent e) { }

    @Override
    public void keyTyped(KeyEvent e) {  }
    } 
  }

De implementatie van de GUI


import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
 
public class VierkantenFrame extends JFrame {
  
  public VierkantenFrame() {
    super();
    initialize();
  }

  /**
   * Tekent tien blauwe vierkanten op random locaties
   */
  private void initialize() {
    setTitle("Vierkanten");
    setSize(500, 500);
    
    Container pane = getContentPane();
    pane.setLayout(null);
    pane.setBackground(Color.WHITE);

    for (int i = 0; i < 10; i++) {
      Vierkant vierkant = new Vierkant(Color.BLUE);
      vierkant.setLocation((int)(400 * Math.random()),
                           (int)(400 * Math.random()));
      pane.add(vierkant);
    }
  }
  
  public static void main(String[] arg) {
    VierkantenFrame frame = new VierkantenFrame();
    frame.setVisible(true);
    frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
  }
}

Dynamische tabellen maken met ng2-smart-table

Tijdens het ontwikkelen van applicaties komt het regelmatig voor dat je een dynamische tabel nodig hebt. Nu ben ik de laatste tijd bezig met applicaties te ontwikkelen in Angular 2 en kon ik het moeilik=jk voor elkaar krijgen om een geschikte plug-in te krijgen die werkt in Angular 2….volgt nog

Angular 2 Smart Table Component

ng2-smart-table component made with ❤️ by Akveo team. Follow us on Twitter to get latest news about this component first!

Demo

Live Demo

alt tag

Installation

The library is available as npm package, so all you need to do is to run the following command:

npm install --save ng2-smart-table

This command will create a record in your package.json file and install the package into the npm modules folder.

Minimal Setup Example

First thing you need to do is to import the ng2-smart-table directives into your component.


import { Ng2SmartTableModule } from 'ng2-smart-table';

Then register it by adding to the list of directives of your module:

// ...

@NgModule({
  imports: [
    // ...

    Ng2SmartTableModule,

    // ...
  ],
  declarations: [ ... ]
})
// ...

Now, we need to configure the table and add it into the template. The only required setting for the component to start working is a columns configuration. Let’s register settings property inside of the component where we want to have the table and configure some columns Settings documentation:

settings = {
  columns: {
    id: {
      title: 'ID'
    },
    name: {
      title: 'Full Name'
    },
    username: {
      title: 'User Name'
    },
    email: {
      title: 'Email'
    }
  }
};

Finally let’s put the ng2-smart-table component inside of the template:

// ...

@Component({
  template: `
    <ng2-smart-table [settings]="settings"></ng2-smart-table>
  `
})
// ...

At this step you will have a minimally configured table. All functions are available by default and you don’t need to configure them somehow, so you already able to add/edit/delete rows, sort or filter the table, etc.

But it feels like something is missing… Right, there is no data in the table by default. To add some, let’s create an array property with a list of objects in the component. Please note that object keys are same as in the columns configuration.

data = [
  {
    id: 1,
    name: "Leanne Graham",
    username: "Bret",
    email: "Sincere@april.biz"
  },
  {
    id: 2,
    name: "Ervin Howell",
    username: "Antonette",
    email: "Shanna@melissa.tv"
  },

  // ... list of items

  {
    id: 11,
    name: "Nicholas DuBuque",
    username: "Nicholas.Stanton",
    email: "Rey.Padberg@rosamond.biz"
  }
];

And pass the data to the table:

// ...

@Component({
  template: `
    <ng2-smart-table [settings]="settings" [source]="data"></ng2-smart-table>
  `
})
// ...

Now you have some data in the table.

Further Documentation

Installation, customization and other useful articles: https://akveo.github.io/ng2-smart-table/

How can I support developers?

  • Star our GitHub repo ⭐️
  • Create pull requests, submit bugs, suggest new features or documentation updates 🔧
  • Follow us on Twitter 🐾
  • Like our page on Facebook 👍

Can I hire you guys?

Yes! Visit our homepage or simply leave us a note to contact@akveo.com. We will be happy to work with you!

Features

  • Local data source (Server/API DataSource is on its way)
  • Filtering
  • Sorting
  • Pagination
  • Inline Add/Edit/Delete
  • Flexible event model

License

MIT license.

From akveo

Enjoy 🤘 We’re always happy to hear your feedback!

NPM Package.json explanation

package.json

Specifics of npm’s package.json handling

This document is all you need to know about what’s required in your package.json file. It must be actual JSON, not just a JavaScript object literal.

A lot of the behavior described in this document is affected by the config settings described in npm-config.

The most important things in your package.json are the name and version fields. Those are actually required, and your package won’t install without them. The name and version together form an identifier that is assumed to be completely unique. Changes to the package should come along with changes to the version.

The name is what your thing is called.

Some rules:

  • The name must be less than or equal to 214 characters. This includes the scope for scoped packages.
  • The name can’t start with a dot or an underscore.
  • New packages must not have uppercase letters in the name.
  • The name ends up being part of a URL, an argument on the command line, and a folder name. Therefore, the name can’t contain any non-URL-safe characters.

Some tips:

  • Don’t use the same name as a core Node module.
  • Don’t put “js” or “node” in the name. It’s assumed that it’s js, since you’re writing a package.json file, and you can specify the engine using the “engines” field. (See below.)
  • The name will probably be passed as an argument to require(), so it should be something short, but also reasonably descriptive.
  • You may want to check the npm registry to see if there’s something by that name already, before you get too attached to it. https://www.npmjs.com/

A name can be optionally prefixed by a scope, e.g. @myorg/mypackage. See npm-scope for more detail.

The most important things in your package.json are the name and version fields. Those are actually required, and your package won’t install without them. The name and version together form an identifier that is assumed to be completely unique. Changes to the package should come along with changes to the version.

Version must be parseable by node-semver, which is bundled with npm as a dependency. (npm install semver to use it yourself.)

More on version numbers and ranges at semver.

Put a description in it. It’s a string. This helps people discover your package, as it’s listed in npm search.

Put keywords in it. It’s an array of strings. This helps people discover your package as it’s listed in npm search.

The url to the project homepage.

NOTE: This is not the same as “url”. If you put a “url” field, then the registry will think it’s a redirection to your package that has been published somewhere else, and spit at you.

Literally. Spit. I’m so not kidding.

The url to your project’s issue tracker and / or the email address to which issues should be reported. These are helpful for people who encounter issues with your package.

It should look like this:

{ "url" : "https://github.com/owner/project/issues"
, "email" : "project@hostname.com"
}

You can specify either one or both values. If you want to provide only a url, you can specify the value for “bugs” as a simple string instead of an object.

If a url is provided, it will be used by the npm bugs command.

You should specify a license for your package so that people know how they are permitted to use it, and any restrictions you’re placing on it.

If you’re using a common license such as BSD-2-Clause or MIT, add a current SPDX license identifier for the license you’re using, like this:

{ "license" : "BSD-3-Clause" }

You can check the full list of SPDX license IDs. Ideally you should pick one that is OSIapproved.

If your package is licensed under multiple common licenses, use an SPDX license expression syntax version 2.0 string, like this:

{ "license" : "(ISC OR GPL-3.0)" }

If you are using a license that hasn’t been assigned an SPDX identifier, or if you are using a custom license, use a string value like this one:

{ "license" : "SEE LICENSE IN <filename>" }

Then include a file named <filename> at the top level of the package.

Some old packages used license objects or a “licenses” property containing an array of license objects:

// Not valid metadata
{ "license" :
  { "type" : "ISC"
  , "url" : "http://opensource.org/licenses/ISC"
  }
}

// Not valid metadata
{ "licenses" :
  [
    { "type": "MIT"
    , "url": "http://www.opensource.org/licenses/mit-license.php"
    }
  , { "type": "Apache-2.0"
    , "url": "http://opensource.org/licenses/apache2.0.php"
    }
  ]
}

Those styles are now deprecated. Instead, use SPDX expressions, like this:

{ "license": "ISC" }

{ "license": "(MIT OR Apache-2.0)" }

Finally, if you do not wish to grant others the right to use a private or unpublished package under any terms:

{ "license": "UNLICENSED"}

Consider also setting "private": true to prevent accidental publication.

The “author” is one person. “contributors” is an array of people. A “person” is an object with a “name” field and optionally “url” and “email”, like this:

{ "name" : "Barney Rubble"
, "email" : "b@rubble.com"
, "url" : "http://barnyrubble.tumblr.com/"
}

Or you can shorten that all into a single string, and npm will parse it for you:

"Barney Rubble <b@rubble.com> (http://barnyrubble.tumblr.com/)"

Both email and url are optional either way.

npm also sets a top-level “maintainers” field with your npm user info.

The “files” field is an array of files to include in your project. If you name a folder in the array, then it will also include the files inside that folder. (Unless they would be ignored by another rule.)

You can also provide a “.npmignore” file in the root of your package or in subdirectories, which will keep files from being included, even if they would be picked up by the files array. The .npmignore file works just like a .gitignore.

Certain files are always included, regardless of settings:

  • package.json
  • README (and its variants)
  • CHANGELOG (and its variants)
  • LICENSE / LICENCE

Conversely, some files are always ignored:

  • .git
  • CVS
  • .svn
  • .hg
  • .lock-wscript
  • .wafpickle-N
  • *.swp
  • .DS_Store
  • ._*
  • npm-debug.log

The main field is a module ID that is the primary entry point to your program. That is, if your package is named foo, and a user installs it, and then does require("foo"), then your main module’s exports object will be returned.

This should be a module ID relative to the root of your package folder.

For most modules, it makes the most sense to have a main script and often not much else.

A lot of packages have one or more executable files that they’d like to install into the PATH. npm makes this pretty easy (in fact, it uses this feature to install the “npm” executable.)

To use this, supply a bin field in your package.json which is a map of command name to local file name. On install, npm will symlink that file into prefix/bin for global installs, or ./node_modules/.bin/ for local installs.

For example, myapp could have this:

{ "bin" : { "myapp" : "./cli.js" } }

So, when you install myapp, it’ll create a symlink from the cli.js script to/usr/local/bin/myapp.

If you have a single executable, and its name should be the name of the package, then you can just supply it as a string. For example:

{ "name": "my-program"
, "version": "1.2.5"
, "bin": "./path/to/program" }

would be the same as this:

{ "name": "my-program"
, "version": "1.2.5"
, "bin" : { "my-program" : "./path/to/program" } }

Specify either a single file or an array of filenames to put in place for the man program to find.

If only a single file is provided, then it’s installed such that it is the result from man <pkgname>, regardless of its actual filename. For example:

{ "name" : "foo"
, "version" : "1.2.3"
, "description" : "A packaged foo fooer for fooing foos"
, "main" : "foo.js"
, "man" : "./man/doc.1"
}

would link the ./man/doc.1 file in such that it is the target for man foo

If the filename doesn’t start with the package name, then it’s prefixed. So, this:

{ "name" : "foo"
, "version" : "1.2.3"
, "description" : "A packaged foo fooer for fooing foos"
, "main" : "foo.js"
, "man" : [ "./man/foo.1", "./man/bar.1" ]
}

will create files to do man foo and man foo-bar.

Man files must end with a number, and optionally a .gz suffix if they are compressed. The number dictates which man section the file is installed into.

{ "name" : "foo"
, "version" : "1.2.3"
, "description" : "A packaged foo fooer for fooing foos"
, "main" : "foo.js"
, "man" : [ "./man/foo.1", "./man/foo.2" ]
}

will create entries for man foo and man 2 foo

The CommonJS Packages spec details a few ways that you can indicate the structure of your package using a directories object. If you look at npm’s package.json, you’ll see that it has directories for doc, lib, and man.

In the future, this information may be used in other creative ways.

Tell people where the bulk of your library is. Nothing special is done with the lib folder in any way, but it’s useful meta info.

If you specify a bin directory in directories.bin, all the files in that folder will be added.

Because of the way the bin directive works, specifying both a bin path and setting directories.bin is an error. If you want to specify individual files, use bin, and for all the files in an existing bin directory, use directories.bin.

A folder that is full of man pages. Sugar to generate a “man” array by walking the folder.

Put markdown files in here. Eventually, these will be displayed nicely, maybe, someday.

Put example scripts in here. Someday, it might be exposed in some clever way.

Specify the place where your code lives. This is helpful for people who want to contribute. If the git repo is on GitHub, then the npm docs command will be able to find you.

Do it like this:

"repository" :
  { "type" : "git"
  , "url" : "https://github.com/npm/npm.git"
  }

"repository" :
  { "type" : "svn"
  , "url" : "https://v8.googlecode.com/svn/trunk/"
  }

The URL should be a publicly available (perhaps read-only) url that can be handed directly to a VCS program without any modification. It should not be a url to an html project page that you put in your browser. It’s for computers.

For GitHub, GitHub gist, Bitbucket, or GitLab repositories you can use the same shortcut syntax you use for npm install:

"repository": "npm/npm"

"repository": "gist:11081aaa281"

"repository": "bitbucket:example/repo"

"repository": "gitlab:another/repo"

The “scripts” property is a dictionary containing script commands that are run at various times in the lifecycle of your package. The key is the lifecycle event, and the value is the command to run at that point.

See npm-scripts to find out more about writing package scripts.

A “config” object can be used to set configuration parameters used in package scripts that persist across upgrades. For instance, if a package had the following:

{ "name" : "foo"
, "config" : { "port" : "8080" } }

and then had a “start” command that then referenced thenpm_package_config_port environment variable, then the user could override that by doing npm config set foo:port 8001.

See npm-config and npm-scripts for more on package configs.

Dependencies are specified in a simple object that maps a package name to a version range. The version range is a string which has one or more space-separated descriptors. Dependencies can also be identified with a tarball or git URL.

Please do not put test harnesses or transpilers in your dependencies object. See devDependencies, below.

See semver for more details about specifying version ranges.

  • version Must match version exactly
  • >version Must be greater than version
  • >=version etc
  • <version
  • <=version
  • ~version “Approximately equivalent to version” See semver
  • ^version “Compatible with version” See semver
  • 1.2.x 1.2.0, 1.2.1, etc., but not 1.3.0
  • http://... See ‘URLs as Dependencies’ below
  • * Matches any version
  • "" (just an empty string) Same as *
  • version1 - version2 Same as >=version1 <=version2.
  • range1 || range2 Passes if either range1 or range2 are satisfied.
  • git... See ‘Git URLs as Dependencies’ below
  • user/repo See ‘GitHub URLs’ below
  • tag A specific version tagged and published as tag See npm-tag
  • path/path/path See Local Paths below

For example, these are all valid:

{ "dependencies" :
  { "foo" : "1.0.0 - 2.9999.9999"
  , "bar" : ">=1.0.2 <2.1.2"
  , "baz" : ">1.0.2 <=2.3.4"
  , "boo" : "2.0.1"
  , "qux" : "<1.0.0 || >=2.3.1 <2.4.5 || >=2.5.2 <3.0.0"
  , "asd" : "http://asdf.com/asdf.tar.gz"
  , "til" : "~1.2"
  , "elf" : "~1.2.3"
  , "two" : "2.x"
  , "thr" : "3.3.x"
  , "lat" : "latest"
  , "dyl" : "file:../dyl"
  }
}

You may specify a tarball URL in place of a version range.

This tarball will be downloaded and installed locally to your package at install time.

Git urls can be of the form:

git://github.com/user/project.git#commit-ish
git+ssh://user@hostname:project.git#commit-ish
git+ssh://user@hostname/project.git#commit-ish
git+http://user@hostname/project/blah.git#commit-ish
git+https://user@hostname/project/blah.git#commit-ish

The commit-ish can be any tag, sha, or branch which can be supplied as an argument to git checkout. The default is master.

As of version 1.1.65, you can refer to GitHub urls as just “foo”: “user/foo-project”. Just as with git URLs, a commit-ish suffix can be included. For example:

{
  "name": "foo",
  "version": "0.0.0",
  "dependencies": {
    "express": "visionmedia/express",
    "mocha": "visionmedia/mocha#4727d357ea"
  }
}

As of version 2.0.0 you can provide a path to a local directory that contains a package. Local paths can be saved using npm install -S or npm install --save, using any of these forms:

../foo/bar
~/foo/bar
./foo/bar
/foo/bar

in which case they will be normalized to a relative path and added to yourpackage.json. For example:

{
  "name": "baz",
  "dependencies": {
    "bar": "file:../foo/bar"
  }
}

This feature is helpful for local offline development and creating tests that require npm installing where you don’t want to hit an external server, but should not be used when publishing packages to the public registry.

If someone is planning on downloading and using your module in their program, then they probably don’t want or need to download and build the external test or documentation framework that you use.

In this case, it’s best to map these additional items in a devDependencies object.

These things will be installed when doing npm link or npm install from the root of a package, and can be managed like any other npm configuration param. See npm-config for more on the topic.

For build steps that are not platform-specific, such as compiling CoffeeScript or other languages to JavaScript, use the prepublish script to do this, and make the required package a devDependency.

For example:

{ "name": "ethopia-waza",
  "description": "a delightfully fruity coffee varietal",
  "version": "1.2.3",
  "devDependencies": {
    "coffee-script": "~1.6.3"
  },
  "scripts": {
    "prepublish": "coffee -o lib/ -c src/waza.coffee"
  },
  "main": "lib/waza.js"
}

The prepublish script will be run before publishing, so that users can consume the functionality without requiring them to compile it themselves. In dev mode (ie, locally running npm install), it’ll run this script as well, so that you can test it easily.

In some cases, you want to express the compatibility of your package with a host tool or library, while not necessarily doing a require of this host. This is usually referred to as a plugin. Notably, your module may be exposing a specific interface, expected and specified by the host documentation.

For example:

{
  "name": "tea-latte",
  "version": "1.3.5",
  "peerDependencies": {
    "tea": "2.x"
  }
}

This ensures your package tea-latte can be installed along with the second major version of the host package tea only. npm install tea-latte could possibly yield the following dependency graph:

├── tea-latte@1.3.5
└── tea@2.2.0

NOTE: npm versions 1 and 2 will automatically install peerDependencies if they are not explicitly depended upon higher in the dependency tree. In the next major version of npm (npm@3), this will no longer be the case. You will receive a warning that the peerDependency is not installed instead. The behavior in npms 1 & 2 was frequently confusing and could easily put you into dependency hell, a situation that npm is designed to avoid as much as possible.

Trying to install another plugin with a conflicting requirement will cause an error. For this reason, make sure your plugin requirement is as broad as possible, and not to lock it down to specific patch versions.

Assuming the host complies with semver, only changes in the host package’s major version will break your plugin. Thus, if you’ve worked with every 1.x version of the host package, use "^1.0" or "1.x" to express this. If you depend on features introduced in 1.5.2, use ">= 1.5.2 < 2".

Array of package names that will be bundled when publishing the package.

If this is spelled "bundleDependencies", then that is also honored.

If a dependency can be used, but you would like npm to proceed if it cannot be found or fails to install, then you may put it in the optionalDependencies object. This is a map of package name to version or url, just like the dependencies object. The difference is that build failures do not cause installation to fail.

It is still your program’s responsibility to handle the lack of the dependency. For example, something like this:

try {
  var foo = require('foo')
  var fooVersion = require('foo/package.json').version
} catch (er) {
  foo = null
}
if ( notGoodFooVersion(fooVersion) ) {
  foo = null
}

// .. then later in your program ..

if (foo) {
  foo.doFooThings()
}

Entries in optionalDependencies will override entries of the same name independencies, so it’s usually best to only put in one place.

You can specify the version of node that your stuff works on:

{ "engines" : { "node" : ">=0.10.3 <0.12" } }

And, like with dependencies, if you don’t specify the version (or if you specify “*” as the version), then any version of node will do.

If you specify an “engines” field, then npm will require that “node” be somewhere on that list. If “engines” is omitted, then npm will just assume that it works on node.

You can also use the “engines” field to specify which versions of npm are capable of properly installing your program. For example:

{ "engines" : { "npm" : "~1.0.20" } }

Note that, unless the user has set the engine-strict config flag, this field is advisory only.

This feature was deprecated with npm 3.0.0

Prior to npm 3.0.0, this feature was used to treat this package as if the user had set engine-strict.

You can specify which operating systems your module will run on:

"os" : [ "darwin", "linux" ]

You can also blacklist instead of whitelist operating systems, just prepend the blacklisted os with a ‘!’:

"os" : [ "!win32" ]

The host operating system is determined by process.platform

It is allowed to both blacklist, and whitelist, although there isn’t any good reason to do this.

If your code only runs on certain cpu architectures, you can specify which ones.

"cpu" : [ "x64", "ia32" ]

Like the os option, you can also blacklist architectures:

"cpu" : [ "!arm", "!mips" ]

The host architecture is determined by process.arch

If your package is primarily a command-line application that should be installed globally, then set this value to true to provide a warning if it is installed locally.

It doesn’t actually prevent users from installing it locally, but it does help prevent some confusion if it doesn’t work as expected.

If you set "private": true in your package.json, then npm will refuse to publish it.

This is a way to prevent accidental publication of private repositories. If you would like to ensure that a given package is only ever published to a specific registry (for example, an internal registry), then use the publishConfig dictionary described below to override the registry config param at publish-time.

This is a set of config values that will be used at publish-time. It’s especially handy if you want to set the tag, registry or access, so that you can ensure that a given package is not tagged with “latest”, published to the global public registry or that a scoped module is private by default.

Any config values can be overridden, but of course only “tag”, “registry” and “access” probably matter for the purposes of publishing.

See npm-config to see the list of config options that can be overridden.

npm will default some values based on package contents.

  • "scripts": {"start": "node server.js"}

    If there is a server.js file in the root of your package, then npm will default the start command to node server.js.

  • "scripts":{"preinstall": "node-gyp rebuild"}

    If there is a binding.gyp file in the root of your package, npm will default the preinstall command to compile using node-gyp.

  • "contributors": [...]

    If there is an AUTHORS file in the root of your package, npm will treat each line as a Name <email> (url) format, where email and url are optional. Lines which start with a # or are blank, will be ignored.

Angular 2 cli update to 2.3.0

To update angular-cli to a new version, you must update both the global package and your project’s local package.

Global package:

npm uninstall -g angular-cli
npm cache clean
npm install -g angular-cli@latest

Local project package:

rm -rf node_modules dist tmp
npm install --save-dev angular-cli@latest
npm install
ng init

Running ng init will check for changes in all the auto-generated files created by ng new and allow you to update yours. You are offered four choices for each changed file: y (overwrite), n (don’t overwrite), d (show diff between your file and the updated file) and h (help).

Carefully read the diffs for each code file, and either accept the changes or incorporate them manually after ng init finishes.

The main cause of errors after an update is failing to incorporate these updates into your code.

You can find more details about changes between versions in CHANGELOG.md.

Development Hints for hacking on angular-cli

Working with master

git clone https://github.com/angular/angular-cli.git
cd angular-cli
npm link

npm link is very similar to npm install -g except that instead of downloading the package from the repo, the just cloned angular-cli/ folder becomes the global package. Any changes to the files in the angular-cli/ folder will immediately affect the global angular-cli package, allowing you to quickly test any changes you make to the cli project.

Now you can use angular-cli via the command line:

ng new foo
cd foo
npm link angular-cli
ng serve

npm link angular-cli is needed because by default the globally installed angular-cli just loads the local angular-cli from the project which was fetched remotely from npm. npm link angular-cli symlinks the global angular-cli package to the local angular-cli package. Now the angular-cli you cloned before is in three places: The folder you cloned it into, npm’s folder where it stores global packages and the angular-cli project you just created.

You can also use ng new foo --link-cli to automatically link the angular-cli package.

Angular 2: Bootstrap Accordion in Angular 2

ACCORDION

The accordion component builds on top of the collapse directive to provide a list of items, with collapsible bodies that are collapsed or expanded by clicking on the item’s header.

Base specifications: bootstrap 3 or bootstrap 4

Example

This content is straight in the template.
I can have markup, too!

Markup

  1. <p>
  2. <button type=“button” class=“btn btn-primary btn-sm”
  3. (click)=“group.isOpen = !group.isOpen”>Toggle last panel
  4. </button>
  5. <button type=“button” class=“btn btn-primary btn-sm”
  6. (click)=“status.isFirstDisabled = ! status.isFirstDisabled”>Enable / Disable first panel
  7. </button>
  8. </p>
  9.  
  10. <div class=“checkbox”>
  11. <label>
  12. <input type=“checkbox” [(ngModel)]=“oneAtATime”>
  13. Open only one at a time
  14. </label>
  15. </div>
  16.  
  17. <accordion [closeOthers]=“oneAtATime”>
  18. <accordion-group heading=“Static Header, initially expanded”
  19. [isOpen]=“status.isFirstOpen”
  20. [isDisabled]=“status.isFirstDisabled”>
  21. This content is straight in the template.
  22. </accordion-group>
  23. <accordion-group *ngFor=“let group of groups” [heading]=“group.title”>
  24. {{ group?.content }}
  25. </accordion-group>
  26. <accordion-group heading=“Dynamic Body Content”>
  27. <p>The body of the accordion group grows to fit the contents</p>
  28. <button type=“button” class=“btn btn-primary btn-sm” (click)=“addItem()”>Add Item</button>
  29. <div *ngFor=“let item of items”>{{item}}</div>
  30. </accordion-group>
  31. <accordion-group #group [isOpen]=“status.open”>
  32. <div accordion-heading>
  33. I can have markup, too!
  34. <i class=“pull-right glyphicon”
  35. [ngClass]=“{‘glyphicon-chevron-down’: group?.isOpen, ‘glyphicon-chevron-right’: !group?.isOpen}”></i>
  36. </div>
  37. This is just some content to illustrate fancy headings.
  38. </accordion-group>
  39. </accordion>

Api

Usage

import { AccordionModule } from 'ng2-bootstrap/ng2-bootstrap';
// or
import { AccordionModule } from 'ng2-bootstrap/components/accordion';

Annotations

// component Accordion
@Component({
  selector: 'accordion',
  template: `<ng-content></ng-content>`
})
export class AccordionComponent {
  @Input() public closeOthers:boolean;

  @HostBinding('class.panel-group')
  public addClass = true;
}

// component AccordionGroup
@Component({
  selector: 'accordion-group',
})
export class AccordionGroupComponent implements OnInit, OnDestroy {
  @Input() public heading:string;
  @Input() public panelClass:string;
  @Input() public isDisabled:boolean;

  @HostBinding('class.panel-open')
  @Input() public get isOpen();

  // should be inside of Accordion element
  constructor(private accordion:Accordion) {}
}

Accordion properties

  • closeOthers (?boolean=false) – if true expanding one item will close all others

Accordion Group properties

  • heading (?string='') – clickable text in accordion’s group header, check accordion heading below for using html in header
  • isOpen (?boolean=false) – is accordion group open or closed
  • isDisabled (?boolean=false) – if true disables accordion group
  • panelClass (?string='panel-default') – provides an ability to use Bootstrap’s contextual panel classes (panel-primary, panel-success, panel-info, etc…). List of all available classes link

Accordion heading

Instead of the heading attribute on the accordion-group, you can use an accordion-heading attribute on any element inside a group that will be used as the group’s header template.

Properties parser

properties-parser

A parser for .properties files written in javascript

A parser for .properties files written in javascript. Properties files store key-value pairs. They are typically used for configuration and internationalization in Java applications as well as in Actionscript projects. Here’s an example of the format:

# You are reading the ".properties" entry.
! The exclamation mark can also mark text as comments.
website = http://en.wikipedia.org/
language = English
# The backslash below tells the application to continue reading
# the value onto the next line.
message = Welcome to \
          Wikipedia!
# Add spaces to the key
key\ with\ spaces = This is the value that could be looked up with the key "key with spaces".
# Unicode
tab : \u0009

(taken from Wikipedia)

Currently works with any version of node.js.

  • parse(text): Parses text into key-value pairs. Returns an object containing the key-value pairs.
  • read(path[, callback]): Opens the file specified by path and calls parse on its content. If the optional callback parameter is provided, the result is then passed to it as the second parameter. If an error occurs, the error object is passed to callback as the first parameter. If callback is not provided, the file specified by path is synchronously read and calls parse on its contents. The resulting object is immediately returned.
  • createEditor([path][, options][, callback]]): If neither path or callback are provided an empty editor object is returned synchronously. If only path is provided, the file specified by path is synchronously read and parsed. An editor object with the results in then immediately returned. If both path and callback are provided, the file specified by path is read and parsed asynchronously. An editor object with the results are then passed to callback as the second parameters. If an error occurs, the error object is passed to callback as the first parameter. The following options are supported:
    • options.separator: The character used to separate key/values. Defaults to “=”.
    • options.path: Treated the same way as the optional path argument. If both are provided the arguement wins.
    • options.callback: Treated the same way as the optional callback parameter. If both are provided the arguement wins.
  • Editor: The editor object is returned by createEditor. Has the following API:
    • get(key): Returns the value currently associated with key.
    • set(key, [value[, comment]]): Associates key with value. An optional comment can be provided. If value is not specified or is null, then key is unset.
    • unset(key): Unsets the specified key.
    • save([path][, callback]]): Writes the current contents of this editor object to a file specified by path. If path is not provided, then it’ll be defaulted to the path value passed to createEditor. The callback parameter is called when the file has been written to disk.
    • addHeadComment: Added a comment to the head of the file.
    • toString: Returns the string representation of this properties editor object. This string will be written to a file if save is called.

The easiest way to get node-properties-parser is with npm:

npm install properties-parser

Alternatively you can clone this git repository:

git://github.com/xavi-/node-properties-parser.git
  • Xavi Ramirez

This project is released under The MIT License.

properties reader in node js

properties-reader

Properties file reader for Node.js

An ini file compatible properties reader for Node.JS

Installation

The easiest installation is through NPM:

npm install properties-reader

Or clone the repo https://github.com/steveukx/properties and include the /src/PropertiesReader.js script.

API

Read properties from a file:

var PropertiesReader = require('properties-reader');
var properties = PropertiesReader('/path/to/properties.file');

The properties are then accessible either by fully qualified name, or if the property names are in dot-delimited notation, they can be access as an object:

// fully qualified name
var property = properties.get('some.property.name');

// by object path
var property = properties.path().some.property.name;

To read more than one file, chain calls to the .append() method:

properties.append('/another.file').append('/yet/another.file');

To read properties from a string, use the .read() method:

properties.read('some.property = Value \n another.property = Another Value');

To set a single property into the properties object, use .set():

properties.set('property.name', 'Property Value');

When reading a .ini file, sections are created by having a line that contains just a section name in square brackets. The section name is then prefixed to all property names that follow it until another section name is found to replace the current section.

# contents of properties file
[main]
some.thing = foo

[blah]
some.thing = bar

// reading these back from the properties reader
properties.get('main.some.thing') == 'foo';
properties.get('blah.some.thing') == 'bar';

Checking for the current number of properties that have been read into the reader:

var propertiesCount = properties.length;

The length is calculated on request, so if accessing this in a loop an efficiency would be achieved by caching the value.

When duplicate names are found in the properties, the first one read will be replaced with the later one.

To get the complete set of properties, either loop through them with the .each((key, value) => {}) iterator or use the convenience method getAllProperties to return the complete set of flattened properties.

Data Types

Properties will automatically be converted to their regular data types when they represent true/false or numeric values. To get the original value without any parsing / type coercion applied, use properties.getRaw('path.to.prop').

Contributions

If you find bugs or want to change functionality, feel free to fork and pull request.

 

 

angular 2 spring boot application

Angular2Boot is in sync with Angular 2.0.0, see the Angular release notes !

LATEST NEWS ! Angular2Boot will be presented at JavaOne 2016 this year ! We hope to meet your there and discuss with you !

Angular2Boot is an opiniated framework to build web applications in Java 8. It is built upon rock-solid foundations : Angular 2, GWT and Spring Boot. You can of course use it with any Java backend, like JavaEE with JAX-RS Web services or whatever else.

It provides a very effective way to build Single Page Applications. The development mode is iterative and quick (live code reload), with the strongly typed qualities of Java and the functionalities brought by modern IDEs. The produced code is easy to deploy (relying on one jar only), robust (runs on the JVM) and optimized (Angular 2 change detection and GWT optimized compilation).

Build a starting application in less than 5 minutes and enter into the details to get most of Angular2Boot !

Here is a presentation video (in French) of how it works, at the Toulouse Angular User Group in June 2016.

Summary of this document

How to build an application from the official archetype ?

Use the archetype which builds a fully working Angular2 + SpringBoot application :

mvn archetype:generate \
  -DarchetypeGroupId=fr.lteconsulting \
  -DarchetypeArtifactId=angular2-gwt.archetype \
  -DarchetypeVersion=1.6

Note about the version : you can use either the latest release version like in the example above, or the next snapshot version (1.6-SNAPSHOT in this case) and benefit from the latest improvements and bug fixes. Features only available in the snapshot version are marked in the documentation. You can expect a new release few days after new features are tested and validated.

Enter the desired groupId, artifactId, version and package and your application will be created in a sub directory named after the choosen artifactId.

Enter into this directory and build your application :

mvn clean install

Everything should work fine. Now you can run the built application with this :

java -jar target/YOUR_ARTIFACT_ID.jar

This will launch the SpringBoot application with a minimal client side Angular 2 controller. When entering http://localhost:8080 in your browser, a page should load and show a “Your application is working !” message. This is the sign that everything has been bootstraped correctly and that you can begin to work. There is also an input box, if you change its content the previous title will change too. That’s shows that the two-way Angular data binding is working in your application !

Development mode

During development, building the entire application is too time-consuming. In order to save your time, you can stop the java process we just launched and launch the SpringBoot development mode instead :

mvn spring-boot:run

This will allow to have hot swapping of classes on the server side (to a certain extent, see documentation).

You may also want to hot reload client classes when you change them. In this case you need to start the GWT Super Dev Mode. But that has to be done in another terminal because we don’t want to stop the Spring Boot server !

mvn gwt:run-codeserver

You can open the application project in your IDE (see the chapter on configuration problems that can happen), work on the code and refresh in the browser to get live updates.

And now, what’s next ?

Now that you have a working boostrapped application, you can either continue reading to get more details about what is inside the application you just created. Or you can jump into the Tour of Heroes tutorial to learn the basic concepts of Angular 2 and about creating an Angular2Boot application.

You can also read the cookbook to learn advanced and deepened techniques.

Typically you will want to :

  • add new Angular components to your application. Use the Angular documentation and the Angular2Boot reference below.
  • add new REST services on the backend with SpringBoot,

Anatomy of the generated project

The project you have just built contains already several components. If you inspect the pom.xml file, you will see that the project inherits from spring-boot-starter-parent which is a way to bootstrap a SpringBoot application. The main dependencies your project has are :

  • spring-boot-starter-web: just enough Spring Boot to serve static files and REST services.
  • gwt-user and gwt-dev: GWT runtime and compiler, needed to compile the front side of the application.
  • angular2-gwt: Angular 2 bindings and tools for GWT.

Regarding the project build, only two plugins are used: gwt-maven-plugin and spring-boot-maven-plugin.

Static resources are served from the src/main/resources/static directory. You can add more files there and they will be then accessible from the browser.

index.html

Appart from all the .js files which are the required runtime scripts, the most important file in the src/main/resources/static directory is index.html. The browser loads this page to run your application and it contains everything needed to bootstrap it.

Let’s inspect some parts of it. You will find a <base href='/'> tag which is needed by Angular to make the routing component work in the default mode. Note that you can remove it if you don’t make use of the Router (we will see Routing details later) or if you use the router with the hash strategy on.

Then you will see a bunch of several <link> and <script> tag to load bootstrap.css (this can be removed) and javascript files. Those provide the Angular runtime which is called by your Java/GWT application.

As we talk about it, the javascript file generated from your Java code is imported by this line :

<script src="angular2gwt/angular2gwt.nocache.js"></script>

This script bootstraps GWT’s core and call your application entry point which is the onModuleLoad method of the Application class (which in turn bootstraps Angular with your Java component classes).

The last remarkable thing in this file is this line :

<my-app class="container">Application is loading...</my-app>

This tag is rendered as a <div> until all scripts are loaded. During this period, the “Application is loading” message is displayed. Once the application is initialized, the Angular engine runs and replaces the <my-app> content by the one of the ApplicationComponent.

We will see that just after the Application class.

Application.java

This class is the entrypoint of your application, meaning that its onModuleLoad method will be the first to be called and it will be called just after the GWT runtime has been initialized.

Angular2Boot entrypoint classes are very simple, the only thing you find is the Angular bootstrapping call :

PlatformBrowserDynamic
  .platformBrowserDynamic()
  .bootstrapModule( ApplicationModule_AngularModule.getNgModulePrototype() );

The bootstrapModule method corresponds to the bootstrapModule function of Angular 2’s PlatformBrowserDynamic module. In fact it is bound to Java through GWT’s JsInterop, so behind the scene it is the same function that is called. The parameter of the bootstrapModule is the result of a call to the ApplicationModule_AngularModule.getNgModulePrototype() method. This method returns an Angular2-compatible constructor of the ApplicationModule class. The ApplicationModule_AngularModule class is automatically generated for you by Angular2Boot, as you will see later on.

So here we just say to Angular to start with the ApplicationModule as the root module of our application.

Just one word on the commented line of code that shows :

/** You can uncomment that line to switch Angular to Production mode */
// Core.enableProdMode();

By default, until this line is uncommented Angular will work in debug mode : it will produce helper messages in the console and also add more runtime data associated with the components of the application (helping tools like Augury to work). If you deploy your application, don’t forget to uncomment this line !

ApplicationModule.java

NgModules first appeared in the rc5 version of Angular2. They allow you to split your application into big functional blocks and reuse them in other applications. They allow the Angular tool to perform more optimizations for you : the modules are statically analyzed by the Angular Ahead of Time Compiler (ngc) and some pruning can happen.

Naturally, your java application too should declare a module. This is done in the ApplicationModule class. It reads :

@NgModule(
	imports = {
		BrowserModule.class,
		FormsModule.class },
	declarations = ApplicationComponent.class,
	bootstrap = ApplicationComponent.class )
@JsType
public class ApplicationModule
{
}

It defines the root module of our application. It imports the Angular BrowserModule and FormsModule. The first one brings everything that is needed to make Angular 2 work in the browser (as you may know, Angular can run in other environments than browsers) and the second one (FromsModule) brings useful usual form directives like ngModel. The module then declares the ApplicationComponent component so that it is avalaible to other modules if needed. The bootstrap parameter says that when the module is bootstrapped, it starts with the ApplicationComponent component, which we will examine right now.

ApplicationComponent.java

Here is the source code of the main component application :

@Component(
	selector = "my-app",
	template = "<h1>{ {title}}</h1>" +
  	"You can edit the title by changing the text in this box :<br/>"+
  	"<input [(ngModel)]='title'/>" )
@JsType
public class ApplicationComponent
{
	@JsProperty
	private String title = "Your application is working !";
}

It doesn’t do much but it already uses some of the main concepts of Angular : Components. Here are the very necessary two steps to create an Angular component out of a Java class :

  • add the @Component annotation. This generates metadata about your component for Angular. Refer to the Angular documentation about the meaning of this annotation fields. Putting this annotation triggers the generation of the ApplicationComponent_AngularComponent java class.
  • add the @JsType annotation. This tells the GWT compiler to make this class accessible to the Javascript world. This is required in order that Angular can access your Java classes.

Here with selector = "my-app" we set this class to handle the <my-app> html tag. As you will have guessed, the content generated with this component will replace the content inside the <my-app> tag in the index.html page.

The content generated by the component is defined in the template field in the annotation (template = "<h1>{ { title } }</h1> ..."). It uses the double-brace syntax to refer to the title attribute’s value.

The title field is declared like this:

@JsProperty
private String title = "Your application is working !";

The @JsProperty tells the GWT compiler to make the field accesible to the javascript world and to Angular, even thou it is declared private. If it was declared public you would not need to put this annotation (the @JsType annotation on the class itself makes all the public fields and methods accesible to javascript).

If this field’s value change, Angular will know about and the DOM will be updated accordingly (given the change is made inside the angular zone, meaning inside an event handler and so on).

As you can note, the component’s template includes another part : <input [(ngModel)]='title'/>. This creates an input tag whose value is data-bound to the titleattribute of the component object. The ngModel is an angular directive that comes from the FormsModule that is imported in our ApplicationModule. We will dig a bit deeper into this subject later on.

That’s all for the front side of the application for the moment. Now let’s inspect a backend class providing a very basic REST service.

ApplicationController.java

This class contains two parts : one is the REST controller and the other is the main method, called by Spring Boot :

@RestController
@EnableAutoConfiguration
public class ApplicationController
{
	@RequestMapping( "/test" )
	String test()
	{
		return "This is a test";
	}

	public static void main( String[] args ) throws Exception
	{
		SpringApplication.run( ApplicationController.class, args );
	}
}

Tour of Heroes tutorial

This tutorial walks you through the basics of creating an Angular2Boot application. It is strongly advised to read so that you gain the basic knowledge.

The tutorial is based on the official Angular 2 typescript version of the tutorial. As you will see, the Java and Typescript versions are very similar. It means that you will be able to learn new things on Angular2Boot by reading the Typescript documentation !

Using with another backend technology

While Spring Boot provides a very good platform to host your angular application, you may want to use Angular2Boot with another backend like JBoss, Tomcat, Spark or Jetty.

This is completely possible and documentation and archetypes will be provided soon.

It is even possible to use Angular2Boot only for the front-end and get on with a non-Java technology on the server…

Motivation

Angular 2 has been wrapped around Typescript and Dart because they allow elegant metadata specification through annotations. Java also has annotations and is a language of choice when it comes to build robust applications.

Angular 2 is a very good framework to build industry grade web applications. It is based on several years of experience with Angular 1 and is now mature and answers most of the developper needs.

GWT provides (optimized) translation from Java to Javascript and bindings to Angular 2. With the latest GWT version (2.8), the new JsInterop specification allows easy interoperability with Javascript. And the SuperDevMode has been improved so that recompile time is greatly reduced, providing a development experience similar to what a Javascript developper can expect.

Add the simplicity of Spring Boot for server side application development and you get Angular2Boot !

IDE Configuration

Eclipse

You need to install m2e-apt component. Otherwise, everything should work out of the box by importing the maven project.

IntelliJ

Documentation not yet written

Version matrix

Angular version angular2-gwt.archetype versions angular2-gwt versions
2.0.0 1.6, 1.7-SNAPSHOT 1.6, 1.7-SNAPSHOT
2.0.0 rc 6 1.4, 1.5-SNAPSHOT 1.3, 1.4-SNAPSHOT
2.0.0 rc 5 1.3, 1.4-SNAPSHOT 1.2, 1.3-SNAPSHOT
2.0.0 beta 17 1.1, 1.2-SNAPSHOT 1.0, 1.1-SNAPSHOT
2.0.0 beta 16 1.0 1.0

Troubleshooting

Sometimes, after changing a lot of code, the GWT SuperDevMode gets confused and does not manage to update anymore. This is a limitation caused by GWT. One way to circumvent this is to clear the project and build it again, but it’s time consumming. Another way of doing so it to quit the GWT SuperDevMode and to run the rm -rf target/gwt-unitCache/ command. This will clear GWT compilation cache. You can then restart the GWT SuperDevMode (mvn gwt:run-codeserver) and things should work fine again.

Contact

If you have any question or remark, feel free to use the comment zone at the bottom of the page or to email us directly to contact@lteconsulting.fr.

License: MIT license

Useful links

How to Change JVM Heap Setting (-Xms -Xmx) of Tomcat – Configure setenv.sh file – Run catalina.sh

Apache Tomcat is widely used Web Container in the world. Very big companies run on Apache Tomcat now a days. There are quite a few other alternatives like IBM WebSphere, Geronimo, IIS, etc. but Tomcat is my favorite one too.

It’s very critical for us to configure all correct parameters while running your application in Production environment or even in development env.

In this tutorial we will go over steps on how to configure -Xms, -Xmx and -XX:PermSize value for Tomcat server. Let’s first understand few terms.

-Xmx

Specifies the maximum size, in bytes, of the memory allocation pool. This value must a multiple of 1024 greater than 2MB. Append the letter k or K to indicate kilobytes, or m or M to indicate megabytes. The default value is 64MB. The upper limit for this value will be approximately 4000m on Solaris 7 and Solaris 8 SPARC platforms and 2000m on Solaris 2.6 and x86 platforms, minus overhead amounts. So, in simple words, you are saying Java to use Maximum of 1024 MB from available memory.

NOTE: there is NO SPACE between -Xmx and 1024m

-Xmn

It’s a size of the heap for the young generation.

-XX:PermSize

It’s used to set size for Permanent Generation. It is where class files are kept.

Another must read: Change -Xmx value of Tomcat in Eclipse IDE

Let’s get started:

Below are the simple steps to change -Xmx / -Xms values or other JVM parameters if you are running Tomcat from command prompt.

Step-1

Download Apache Tomcat.

Step-2

Go to Apache Tomcat /bin directory.

Create setevn.sh file for Tomcat Xmx and Xmn value - Crunchify Tips

Step-3

By default you wont see setenv.sh (for Linux/Mac) or setenv.bat (for windows) file under /bindirectory. You have to create one with below parameters.

Step-4

  1. Go to command prompt.
  2. Go to <Tomcat Directory>/bin directory
  3. Execute command: ./catalina.sh run

Run Apache Tomcat using catalina.sh run command - Crunchify

Step-5

Monitor logfile and you should see your Tomcat started with all your specified parameters in setenv.shfile.

Apache Tomcat Log with Xmx and Xmn value - Crunchify Tips

PS: For Windows environment you need to create setenv.bat file and run Tomcat withcatalina.bat

Subscribe to our newsletter and never miss a post!

Get early access to new articles, plugins, discount codes and brief updates about what’s new with Crunchify! Join more than 21000 subscribers…

Avatar for App Shah

About App Shah

Hello & Good Day from greater New York. I’m an Engineer & founder of Crunchify, the largest free blogging & technical resource site for beginners. Love SEO, SaaS, #webperf, WordPress, Java. With more than 14 millions pageviews / month, Crunchify LLC, has changed the life of over thousands of individual around the globe teaching Java & Web technology without spending a money online. Get latest update on and .