ReactJS notes, part 1

I’m watching a video series from O’Reilly (also Addison-Wesley, LiveLessons, InformIT, Pearson) called ReactJS Fundamentals, by Charles David Crawford.

Step 1: Install Node. If you’ve installed Homebrew on a Mac, you can install Node with this:

brew install node

Having installed Node, you now have npm, a package manager for JavaScript.

Step 2: Use npm to create a file, package.json, which you can do simply with this command:

npm init

Since you’re just getting started, you can press Return/Enter for each option until you get back to the bare command prompt. Now you have package.json in whatever directory you’re in.

If instead of just hitting Return you wanted to fill in all the options properly, which of course you would do for a real project, here’s a guide. See also this. The package.json file is going to manage all your dependencies for the project, app, site, whatever.

Step 3: Since you’re starting a ReactJS project, you install it like this:

npm install --save react

This created a new file, package-lock.json, and a new folder, node_modules, inside of which is a whole bunch of crap that ReactJS apparently needs. This is why you had to install Node to get npm, etc. — because ReactJS needs all this stuff.

The guy in the video goes through all of this in less than 4 minutes, which is a bit overwhelming if you’ve never used npm or any of this before now.

Important: In a production environment, where you’re committing changes to GitHub, you will commit package.json, but you will add the folder node_modules to your .gitignore file. The package.json file will handle all the dependencies on the server. Therefore, you do NOT want to commit/upload the node_modules folder.

Step 4: Install even more stuff to make it all work.

In the videos, the guy is using Webpack to smush all the JavaScript into one file, so you have only one <script> tag in your HTML. It doesn’t minify the code, though. More about Webpack.

He’s also using Babel, a JavaScript compiler, to convert ES6 for old browsers. He has separate videos explaining these in some detail.

npm install --save-dev webpack -g
npm install --save-dev babel-loader
npm install --save-dev babel-preset-es2016
npm install --save-dev babel-preset-react
npm install --save-dev react-dom

Yeah, I know — it’s a lot. And we haven’t even learned any ReactJS yet.

Step 5: Create webpack.config.js file and write a bunch of things in it.

I’m dying here. The code is not supplied with the library’s link to these video files. At this point I was getting lost because the guy is running code he’s got in the project, but he hasn’t shown us how to write it. I was able to cobble together working code based on a repo I found on GitHub, but I realized at this point I couldn’t continue this course without the code.

In package.json I’ve got (among other code):

"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack"
}

So when I enter the following command, Webpack is invoked, and Webpack runs Babel:

npm run build

Babel applies ES6 transformations and React transformations (because webpack.config.js tells it to; it’s not automatic, and we did install the presets for those). Webpack also bundles all JavaScript files into one concatenated file, creating or rewriting bundle.js in the build directory. The directories app and build, as well as the filename bundle.js, are all set up in webpack.config.js.

Step 6: OMG another install:

npm install --save-dev webpack-dev-server

This is when I abandoned the ReactJS Fundamentals videos, because the guy opened a new set of files with a bunch of new code, and lacking those files, I couldn’t run anything.

jQuery AJAX cheat sheet

I know the Fetch API is probably going to replace AJAX, and soon.

I also know that learning jQuery is less important now than it has been for a number of years.

However, jQuery Ajax commands are very useful, compact, and still necessary for many APIs. So these ready-to-use code snippets for every day can really come in handy when you just need to get some external data into your HTML quickly and easily.

The snippets cover $.get()$.post()$.load(), $.getJSON, JSON.parse() (which is pure JavaScript), and the all-purpose form tool, $.serialize(). They do not cover $.ajax(), which essentially does everything, but with more lines.

Another post in favor of PWAs

This post — Your Site—Any Site—Should be a PWA — makes the argument in its title and also includes some helpful links.

PWAs don’t require you use a particular JavaScript framework or any JavaScript framework at all. You don’t need to be building a Single Page App either. In fact, it will probably be easier if you’re not.

You do, however, need a service worker.

More about using fetch()

From this:

  1. “The fetch() method takes the path to a resource as input.
  2. “The method returns a promise that resolves to the Response of that request.”

Refer to the brief code examples in my earlier post. You’ll see that the .then() statements following the promise are different depending on the expected response data type, e.g. text or JSON.

“Evaluating the success of responses is particularly important when using fetch because bad responses (like 404s) still resolve.” This means that any response at all is a valid response to the fetch() method. The example below looks fine — until you realize that.

fetch('example.json')
.then(function(response) {
   // do stuff with the response
})
.catch(function(error) {
   console.log('Looks like there was a problem: \n', error);
});

So what we really need in the .then() statement is this:

.then(function(response) {
   if (!response.ok) {
      throw Error(response.statusText);
   }
   // do stuff with the response
})

The Response includes response.ok, response.status, response.statusText, etc. Use response.status, for example, to see if you got a 404 or similar error (more info).

The code following the sentence (here) “This code will be cleaner and easier to understand if it’s abstracted into functions” is very helpful. It demonstrates promise chaining and is explained below the code.

The same article contains examples for fetching images and fetching text.

We can add a method such as POST or HEAD (to get metadata) when requesting a resource with fetch (the default method is GET):

fetch( 'examples/words.txt', { method: 'HEAD'} )

Custom headers can be added in the same way (using the init parameter with headers: instead of method:).

Cross-origin requests

These can really mess up your day, as I learned one time when trying to use two APIs together in one web app. Cautions are explained near the end of the resource. It describes how to use no-cors mode with fetch.

  1. Fetch supports Cross Origin Resource Sharing (CORS).
  2. Testing generally requires running a local server.
  3. Note that although fetch does not require HTTPS, service workers do, and so using fetch in a service worker requires HTTPS. Local servers are exempt from this.

If you are using fetch without a service worker, you can use HTTP.

Service worker: Important to PWAs

Service worker: “Essentially a JavaScript file that runs separately from the main browser thread, intercepting network requests, caching or retrieving resources from the cache, and delivering push messages.” Service workers also “provide offline access to cached content.” (Source)

A web worker is “an object created using a constructor (e.g. Worker()) that runs a named JavaScript file — this file contains the code that will run in the worker thread; workers run in another global context that is different from the current window.” (Source)

A service worker is a type of web worker.

How about browser support for service workers? Check here.

A service worker can allow your app to show push notifications even when the app is not open in the browser. This is one of the hallmarks of progressive web apps (PWAs). What about when the browser itself is not open? Android will “wake up any browser when a push message is received” (source), but other operating systems (currently) will not.

“To communicate with the page, the service worker uses the postMessage() method to send data and a ‘message’ event listener to receive data.” (Same source.)

More (from the same source):

  • Service workers only run over HTTPS.
  • Service workers make extensive use of promises.
  • For making an app work offline, service workers depend on these two APIs: Fetch and Cache.
  • When you register a service worker (in your script), you can explicitly set its scope. (“The default scope is the location of the service worker file, and extends to all directories below.”)
  • After the service worker is registered, it is installed, and after that, it is activated. However, activation only occurs after all pages still using the old service worker have been closed. You can never have more than one version of the service worker running concurrently.
  • Use self.addEventListener() to detect 'install' and 'activate' events.

Fetch API: better than AJAX?

“A Promise-based mechanism for programmatically making web requests in the browser.” Replaces most uses of XMLHttpRequest in traditional web applications.

See more links at the end of this post.

Example 1 (run in console):

fetch('http://mindymcadams.com/index.html').then(response => {
   return response.text();
}).then(text => {
   console.log(text);
});

Example 2 (run in console with animals.json file in same dir as the currently open page):

fetch('animals.json').then(response => {
   return response.json();
}).then(json => {
   console.log(json);
});

Each of the examples returns the full contents of the file.

Some good stuff:

  • Working with the Fetch API — this is really clear, step by step, complete (from Google Developers; part of the PWAs workshop, but this can stand alone)
  • Slides that provide an overview of fetch()
  • Introduction to fetch() (also from Google Developers)
  • A window.fetch JavaScript polyfill (on GitHub): “Chrome and Firefox both implement the window.fetch function natively, [so] no code from this project actually takes any effect in these browsers.”
css.php