Npm Use Isit Code

Elvenware Logo

TOC

Overview

This assignment demonstrates how to use your fork of my isit-code package. We will also create an Express and React based project that calls some methods in your fork of isit-code.

Be sure lamp is installed.

Note on Names

To save keystrokes when typing, and cut down on noise when reading, I'll use some simple shortcuts. Unless I explicitly state otherwise, when I write isit-code, I'm referencing your isit-code-lastname project.

Create Projects

Use CreateExpressProject to populate a folder in your repository called Week04-UseIsitCode:

Use NPM to install your isit-code project and save a reference to it in your package.json file.

Methods to call

In index.js use require to load your NPM package. The call might look something like this:

const isitCode = require('isit-code-lastname');

Most of the time, however, you want to load a particule module from the library. Suppose you want the elf-utils module. Load it like this:

const elfUtils = require('isit-code-lastname').elfUtils;

Now call two methods from your isit-code package.

Create two routes in index.js, one for calling each method. The routes should have these names:

For instance:

router.get('/home-directory', function(req, res, next) { 'use strict';

I'll leave it up to you to implement the method. the call to elfUtils.homeDir is very simple. Also, you can see an example of how to call it in isit-code/spec/test-elf-utils-files.js.

NOTE: This is one of the times when a set of unit tests can be used not just for running tests, but for documenting a library. In particular, the primary documentation for isit-code is in the spec directory of the isit-code package. Though it would be good to have better document, it is often the case the unit tests included with a package can help you understand a package.

Client

Create a file called CallIsitCode in a directory in the root of your project called source. The file should contain ES6 and React code.

THREE NOTES ON STYLE:

Create two buttons in your React component:

A click on the first button should call the appropriate method on the server. Click the second button -- and well -- you know what it should do. Use fetch from whatwg-fetch to make the calls from the client to the server.

Webpack

You are going to need to create a webpack.config.js file. I would suggest you copy the one from the webpack section of the ReactBasics assignment.

You will want to put the entry to CallIsitCode. The output might look something like this:

output: {path: __dirname, filename: './public/javascripts/bundle.js'},

Load ES6

You should know the steps to load the ES6 code by now. But if you need a hint, consider this:

The key pieces you need at the end of index.pug are:

We put the script statement at the end of index.html because it uses the home DIV. That DIV must already be loaded or the React code won't find a place to insert itself.

Getting User Input

Suppose you define an input control with JSX:

<input type="text" onChange={this.firstWordChange} placeholder='Enter multi-word sentence.' />

How do we get text from the input? Declare state for the input:

constructor() {
    super();
    this.state = {
        homeDirectory: 'Unknown',
        firstWord: 'Unknown',
        userInput: 'Unknown'   << TRACK USER INPUT
    };
    this.homeDirectory = this.homeDirectory.bind(this);
    this.firstWordChange = this.firstWordChange.bind(this);
    this.firstWord = this.firstWord.bind(this);
}

Define the firstWordChange method. It gets called over and over as the user types in the input. It also continually updates the this.state.userInput:

firstWordChange(event) {
    console.log('firstWord:', event.target.value);
    this.setState({userInput: event.target.value})
}

Passing Parameters with fetch

Now that we have the user input in this.state.userInput, how do we pass it to the server. Like this:

Our goal is to pass a URL to the server describing the sentence from which we want the first word:

/first-word?

First we need to define a method to URL encode the parameters:

getQuery() {
        const params = {sentence: this.state.userInput};
        const encodeUri = encodeURIComponent;
        let query = Object.keys(params)
            .map(key => encodeUri(key) + '=' + encodeUri(params[key]))
            .join('&');
        return query;
    }
}

The join statement turns the array produced by map into a string joined on ampersands.

Then we need to use it when we call fetch:

firstWord() {
    const that = this;
    const query = '/first-word?' + this.getQuery();
    console.log(query);
    fetch(query)
        .then(function(response) {
            return response.json();
        })
        .then(function(json) {
            console.log('parsed json', json);
            that.setState({ firstWord: json.firstWord });
        })
        .catch(function(ex) {
            console.log('parsing failed', ex);
        });
}

Handle code on Server

And here is the code for getting the query when it is passed to the server:

router.get('/first-word', function(request, response, next) { 'use strict';
    console.log(req.query);
    try {
      // Now call elfUtils with the sentence passed in the query.
      // Use Response.send to return the result.
      // Here is one way to handle an error if it occurs:
    } catch(e) {
        console.log(e);
        res.status(500).send(e)
    }
});

Turn it in

Place your work in a branch called Week04. When turning in the assignment, include the following information:

To get full credit, the second button must retrieve a string from the user via a TextBox. The call should retrieve the first word the user enters.

Also, consider adding the URL of your repos:

Cannot read property of undefined

We often get errors like this:

We know that we are calling setState of this or that. So why is this undefined? There could be many reasons, by a likely culprit is that you forgot to bind a method:

this.someMethod = this.someMethod.bind(this);

Finding Code

Read the References section in ElvenLinks