Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Newsletter Hub
Free Learning
Arrow right icon
timer SALE ENDS IN
0 Days
:
00 Hours
:
00 Minutes
:
00 Seconds

How-To Tutorials - Front-End Web Development

341 Articles
article-image-creating-test-suites-specs-and-expectations-jest
Packt
12 Aug 2015
7 min read
Save for later

Creating test suites, specs and expectations in Jest

Packt
12 Aug 2015
7 min read
In this article by Artemij Fedosejev, the author of React.js Essentials, we will take a look at test suites, specs, and expectations. To write a test for JavaScript functions, you need a testing framework. Fortunately, Facebook built their own unit test framework for JavaScript called Jest. It is built on top of Jasmine - another well-known JavaScript test framework. If you’re familiar with Jasmine you’ll find Jest's approach to testing very similar. However I'll make no assumptions about your prior experience with testing frameworks and discuss the basics first. The fundamental idea of unit testing is that you test only one piece of functionality in your application that usually is implemented by one function. And you test it in isolation - meaning that all other parts of your application which that function depends on are not used by your tests. Instead, they are imitated by your tests. To imitate a JavaScript object is to create a fake one that simulates the behavior of the real object. In unit testing the fake object is called mock and the process of creating it is called mocking. Jest automatically mocks dependencies when you're running your tests. Better yet, it automatically finds tests to execute in your repository. Let's take a look at the example. Create a directory called ./snapterest/source/js/utils/ and create a new file called TweetUtils.js within it, with the following contents: function getListOfTweetIds(tweets) {  return Object.keys(tweets);}module.exports.getListOfTweetIds = getListOfTweetIds; TweetUtils.js file is a module with the getListOfTweetIds() utility function for our application to use. Given an object with tweets, getListOfTweetIds() returns an array of tweet IDs. Using the CommonJS module pattern we export this function: module.exports.getListOfTweetIds = getListOfTweetIds; Jest Unit Testing Now let's write our first unit test with Jest. We'll be testing our getListOfTweetIds() function. Create a new directory: ./snapterest/source/js/utils/__tests__/. Jest will run any tests in any __tests__ directories that it finds within your project structure. So it's important to name your directories with tests: __tests__. Create a TweetUtils-test.js file inside of __tests__:jest.dontMock('../TweetUtils');describe('Tweet utilities module', function () {  it('returns an array of tweet ids', function () {    var TweetUtils = require('../TweetUtils');    var tweetsMock = {      tweet1: {},      tweet2: {},      tweet3: {}    };    var expectedListOfTweetIds = ['tweet1', 'tweet2', 'tweet3'];    var actualListOfTweetIds = TweetUtils.getListOfTweetIds(tweetsMock);    expect(actualListOfTweetIds).toBe(expectedListOfTweetIds);  });}); First we tell Jest not to mock our TweetUtils module: jest.dontMock('../TweetUtils'); We do this because Jest will automatically mock modules returned by the require() function. In our test we're requiring the TweetUtils module: var TweetUtils = require('../TweetUtils'); Without the jest.dontMock('../TweetUtils') call, Jest would return an imitation of our TweetUtils module, instead of the real one. But in this case we actually need the real TweetUtils module, because that's what we're testing. Creating test suites Next we call a global Jest function describe(). In our TweetUtils-test.js file we're not just creating a single test, instead we're creating a suite of tests. A suite is a collection of tests that collectively test a bigger unit of functionality. For example a suite can have multiple tests which tests all individual parts of a larger module. In our example, we have a TweetUtils module with a number of utility functions. In that situation we would create a suite for the TweetUtils module and then create tests for each individual utility function, like getListOfTweetIds(). describe defines a suite and takes two parameters: Suite name - the description of what is being tested: 'Tweet utilities module'. Suit implementation: the function that implements this suite. In our example, the suite is: describe('Tweet utilities module', function () {  // Suite implementation goes here...}); Defining specs How do you create an individual test? In Jest, individual tests are called specs. They are defined by calling another global Jest function it(). Just like describe(), it() takes two parameters: Spec name: the title that describes what is being tested by this spec: 'returns an array of tweet ids'. Spec implementation: the function that implements this spec. In our example, the spec is: it('returns an array of tweet ids', function () {  // Spec implementation goes here...}); Let's take a closer look at the implementation of our spec: var TweetUtils = require('../TweetUtils');var tweetsMock = {  tweet1: {},  tweet2: {},  tweet3: {}};var expectedListOfTweetIds = ['tweet1', 'tweet2', 'tweet3'];var actualListOfTweetIds = TweetUtils.getListOfTweetIds(tweetsMock);expect(actualListOfTweetIds).toEqual(expectedListOfTweetIds); This spec tests whether getListOfTweetIds() method of our TweetUtils module returns an array of tweet IDs when given an object with tweets. First we import the TweetUtils module: var TweetUtils = require('../TweetUtils'); Then we create a mock object that simulates the real tweets object: var tweetsMock = {  tweet1: {},  tweet2: {},  tweet3: {}}; The only requirement for this mock object is to have tweet IDs as object keys. The values are not important hence we choose empty objects. Key names are not important either, so we can name them tweet1, tweet2 and tweet3. This mock object doesn't fully simulate the real tweet object. Its sole purpose is to simulate the fact that its keys are tweet IDs. The next step is to create an expected list of tweet IDs: var expectedListOfTweetIds = ['tweet1', 'tweet2', 'tweet3']; We know what tweet IDs to expect because we've mocked a tweets object with the same IDs. The next step is to extract the actual tweet IDs from our mocked tweets object. For that we use getListOfTweetIds()that takes the tweets object and returns an array of tweet IDs: var actualListOfTweetIds = TweetUtils.getListOfTweetIds(tweetsMock); We pass tweetsMock to that method and store the results in actualListOfTweetIds. The reason this variable is named actualListOfTweetIds is because this list of tweet IDs is produced by the actual getListOfTweetIds() function that we're testing. Setting Expectations The final step will introduce us to a new important concept: expect(actualListOfTweetIds).toEqual(expectedListOfTweetIds); Let's think about the process of testing. We need to take an actual value produced by the method that we're testing - getListOfTweetIds(), and match it to the expected value that we know in advance. The result of that match will determine if our test has passed or failed. The reason why we can guess what getListOfTweetIds() will return in advance is because we've prepared the input for it - that's our mock object: var tweetsMock = {  tweet1: {},  tweet2: {},  tweet3: {}}; So we can expect the following output from calling TweetUtils.getListOfTweetIds(tweetsMock): ['tweet1', 'tweet2', 'tweet3'] But because something can go wrong inside of getListOfTweetIds() we cannot guarantee this result - we can only expect it. That's why we need to create an expectation. In Jest, an Expectation is built using expect()which takes an actual value, for example: actualListOfTweetIds. expect(actualListOfTweetIds) Then we chain it with a Matcher function that compares the actual value with the expected value and tells Jest whether the expectation was met. expect(actualListOfTweetIds).toEqual(expectedListOfTweetIds); In our example we use the toEqual() matcher function to compare two arrays. Click here for a list of all built-in matcher functions in Jest. And that's how you create a spec. A spec contains one or more expectations. Each expectation tests the state of your code. A spec can be either a passing spec or a failing spec. A spec is a passing spec only when all expectations are met, otherwise it's a failing spec. Well done, you've written your first testing suite with a single spec that has one expectation. Continue reading React.js Essentials to continue your journey into testing.
Read more
  • 0
  • 0
  • 35447

article-image-building-components-using-angular
Packt
06 Apr 2017
11 min read
Save for later

Building Components Using Angular

Packt
06 Apr 2017
11 min read
In this article by Shravan Kumar Kasagoni, the author of the book Angular UI Development, we will learn how to use new features of Angular framework to build web components. After going through this article you will understand the following: What are web components How to setup the project for Angular application development Data binding in Angular (For more resources related to this topic, see here.) Web components In today's web world if we need to use any of the UI components provided by libraries like jQuery UI, YUI library and so on. We write lot of imperative JavaScript code, we can't use them simply in declarative fashion like HTML markup. There are fundamental problems with the approach. There is no way to define custom HTML elements to use them in declarative fashion. The JavaScript, CSS code inside UI components can accidentally modify other parts of our web pages, our code can also accidentally modify UI components, which is unintended. There is no standard way to encapsulate code inside these UI components. Web Components provides solution to all these problems. Web Components are set of specifications for building reusable UI components. Web Components specifications is comprised of four parts: Templates: Allows us to declare fragments of HTML that can be cloned and inserted in the document by script Shadow DOM: Solves DOM tree encapsulation problem Custom elements: Allows us to define custom HTML tags for UI components HTML imports: Allows to us add UI components to web page using import statement More information on web components can be found at: https://www.w3.org/TR/components-intro/. Component are the fundament building blocks of any Angular application. Components in Angular are built on top of the web components specification. Web components specification is still under development and might change in future, not all browsers supports it. But Angular provides very high abstraction so that we don't need to deal with multiple technologies in web components. Even if specification changes Angular can take care of internally, it provides much simpler API to write web components. Getting started with Angular We know Angular is completely re-written from scratch, so everything is new in Angular. In this article we will discuss few important features like data binding, new templating syntax and built-in directives. We are going use more practical approach to learn these new features. In the next section we are going to look at the partially implemented Angular application. We will incrementally use Angular new features to implement this application. Follow the instruction specified in next section to setup sample application. Project Setup Here is a sample application with required Angular configuration and some sample code. Application Structure Create directory structure, files as mentioned below and copy the code into files from next section. Source Code package.json We are going to use npm as our package manager to download libraries and packages required for our application development. Copy the following code to package.json file. { "name": "display-data", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "tsc": "tsc", "tsc:w": "tsc -w", "lite": "lite-server", "start": "concurrent "npm run tsc:w" "npm run lite" " }, "author": "Shravan", "license": "ISC", "dependencies": { "angular2": "^2.0.0-beta.1", "es6-promise": "^3.0.2", "es6-shim": "^0.33.13", "reflect-metadata": "^0.1.2", "rxjs": "^5.0.0-beta.0", "systemjs": "^0.19.14", "zone.js": "^0.5.10" }, "devDependencies": { "concurrently": "^1.0.0", "lite-server": "^1.3.2", "typescript": "^1.7.5" } } The package.json file holds metadata for npm, in the preceding code snippet there are two important sections: dependencies: It holds all the packages required for an application to run devDependencies: It holds all the packages required only for development Once we add the preceding package.json file to our project we should run the following command at the root of our application. $ npm install The preceding command will create node_modules directory in the root of project and downloads all the packages mentioned in dependencies, devDependencies sections into node_modules directory. There is one more important section, that is scripts. We will discuss about scripts section, when we are ready to run our application. tsconfig.json Copy the below code to tsconfig.json file. { "compilerOptions": { "target": "es5", "module": "system", "moduleResolution": "node", "sourceMap": true, "emitDecoratorMetadata": true, "experimentalDecorators": true, "removeComments": false, "noImplicitAny": false }, "exclude": [ "node_modules" ] } We are going to use TypeScript for developing our Angular applications. The tsconfig.json file is the configuration file for TypeScript compiler. Options specified in this file are used while transpiling our code into JavaScript. This is totally optional, if we don't use it TypeScript compiler use are all default flags during compilation. But this is the best way to pass the flags to TypeScript compiler. Following is the expiation for each flag specified in tsconfig.json: target: Specifies ECMAScript target version: 'ES3' (default), 'ES5', or 'ES6' module: Specifies module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es6' moduleResolution: Specifies module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6) sourceMap: If true generates corresponding '.map' file for .js file emitDecoratorMetadata: If true enables the output JavaScript to create the metadata for the decorators experimentalDecorators: If true enables experimental support for ES7 decorators removeComments: If true, removes comments from output JavaScript files noImplicitAny: If true raise error if we use 'any' type on expressions and declarations exclude: If specified, the compiler will not compile the TypeScript files in the containing directory and subdirectories index.html Copy the following code to index.html file. <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Top 10 Fastest Cars in the World</title> <link rel="stylesheet" href="app/site.css"> <script src="node_modules/angular2/bundles/angular2-polyfills.js"></script> <script src="node_modules/systemjs/dist/system.src.js"></script> <script src="node_modules/rxjs/bundles/Rx.js"></script> <script src="node_modules/angular2/bundles/angular2.dev.js"></script> <script> System.config({ transpiler: 'typescript', typescriptOptions: {emitDecoratorMetadata: true}, map: {typescript: 'node_modules/typescript/lib/typescript.js'}, packages: { 'app' : { defaultExtension: 'ts' } } }); System.import('app/boot').then(null, console.error.bind(console)); </script> </head> <body> <cars-list>Loading...</cars-list> </body> </html> This is startup page of our application, it contains required angular scripts, SystemJS configuration for module loading. Body tag contains <cars-list> tag which renders the root component of our application. However, I want to point out one specific statement: The System.import('app/boot') statement will import boot module from app package. Physically it loading boot.js file under app folder. car.ts Copy the following code to car.ts file. export interface Car { make: string; model: string; speed: number; } We are defining a car model using TypeScript interface, we are going to use this car model object in our components. app.component.ts Copy the following code to app.component.ts file. import {Component} from 'angular2/core'; @Component({ selector: 'cars-list', template: '' }) export class AppComponent { public heading = "Top 10 Fastest Cars in the World"; } Important points about AppComponent class: The AppComponent class is our application root component, it has one public property named 'heading' The AppComponent class is decorated with @Component() function with selector, template properties in its configuration object The @Component() function is imported using ES2015 module import syntax from 'angular2/core' module in Angular library We are also exporting the AppComponent class as module using export keyword Other modules in application can also import the AppComponent class using module name (app.component – file name without extension) using ES2015 module import syntax boot.ts Copy the following code to boot.ts file. import {bootstrap} from 'angular2/platform/browser' import {AppComponent} from './app.component'; bootstrap(AppComponent); In this file we are importing bootstrap() function from 'angular2/platform/browser' module and the AppComponent class from 'app.component' module. Next we are invoking bootstrap() function with the AppComponent class as parameter, this will instantiate an Angular application with the AppComponent as root component. site.css Copy the following code to site.css file. * { font-family: 'Segoe UI Light', 'Helvetica Neue', 'Segoe UI', 'Segoe'; color: rgb(51, 51, 51); } This file contains some basic styles for our application. Working with data in Angular In any typical web application, we need to display data on a HTML page and read the data from input controls on a HTML page. In Angular everything is a component, HTML page is represented as template and it is always associated with a component class. Application data lives on component's class properties. Either push values to template or pull values from template, to do this we need to bind the properties of component class to the controls on the template. This mechanism is known as data binding. Data binding in angular allows us to use simple syntax to push or pull data. When we bind the properties of component class to the controls on the template, if the data on the properties changes, Angular will automatically update the template to display the latest data and vice versa. We can also control the direction of data flow (from component to template, from template to component). Displaying Data using Interpolation If we go back to our AppComponent class in sample application, we have heading property. We need to display this heading property on the template. Here is the revised AppComponent class: app/app.component.ts import {Component} from 'angular2/core'; @Component({ selector: 'cars-list', template: '<h1>{{heading}}</h1>' }) export class AppComponent { public heading = "Top 10 Fastest Cars in the World"; } In @Component() function we updated template property with expression {{heading}} surrounded by h1 tag. The double curly braces are the interpolation syntax in Angular. Any property on the class we need to display on the template, use the property name surrounded by double curly braces. Angular will automatically render the value of property on the browser screen. Let's run our application, go to command line and navigate to the root of the application structure, then run the following command. $ npm start The preceding start command is part of scripts section in package.json file. It is invoking two other commands npm run tsc:w, npm run lite. npm run tsc:w: This command is performing the following actions: It is invoking TypeScript compiler in watch mode TypeScript compiler will compile all our TypeScript files to JavaScript using configuration mentioned in tsconfig.json TypeScript compiler will not exit after the compilation is over, it will wait for changes in TypeScript files Whenever we modify any TypeScript file, on the fly compiler will compile them to JavaScript npm run lite: This command will start a lite weight Node.js web server and launches our application in browser Now we can continue to make the changes in our application. Changes are detected and browser will refresh automatically with updates. Output in the browser: Let's further extend this simple application, we are going to bind the heading property to a textbox, here is revised template: template: ` <h1>{{heading}}</h1> <input type="text" value="{{heading}}"/> ` If we notice the template it is a multiline string and it is surrounded by ` (backquote/ backtick) symbols instead of single or double quotes. The backtick (``) symbols are new multi-line string syntax in ECMAScript 2015. We don't need start our application again, as mentioned earlier it will automatically refresh the browser with updated output until we stop 'npm start' command is at command line. Output in the browser: Now textbox also displaying the same value in heading property. Let's change the value in textbox by typing something, then hit the tab button. We don't see any changes happening on the browser. But as mentioned earlier in data binding whenever we change the value of any control on the template, which is bind to a property of component class it should update the property value. Then any other controls bind to same property should also display the updated value. In browser h1 tag should also display the same text whatever we type in textbox, but it won't happen. Summary We started this article by covering introduction to web components. Next we discussed a sample application which is the foundation for this article. Then we discussed how to write components using new features in Angular to like data binding and new templating syntaxes using lot of examples. By the end of this article, you should have good understanding of Angular new concepts and should be able to write basic components. Resources for Article: Further resources on this subject: Get Familiar with Angular [article] Gearing Up for Bootstrap 4 [article] Angular's component architecture [article]
Read more
  • 0
  • 0
  • 34866

article-image-shapefiles-leaflet
Packt
18 Aug 2014
5 min read
Save for later

Shapefiles in Leaflet

Packt
18 Aug 2014
5 min read
This article written by Paul Crickard III, the author of Leaflet.js Essentials, describes the use of shapefiles in Leaflet. It shows us how a shapefile can be used to create geographical features on a map. This article explains how shapefiles can be used to add a pop up or for styling purposes. (For more resources related to this topic, see here.) Using shapefiles in Leaflet A shapefile is the most common geographic file type that you will most likely encounter. A shapefile is not a single file, but rather several files used to create geographic features on a map. When you download a shapefile, you will have .shp, .shx, and .dbf at a minimum. These files are the shapefiles that contain the geometry, the index, and a database of attributes. Your shapefile will most likely include a projection file (.prj) that will tell that application the projection of the data so the coordinates make sense to the application. In the examples, you will also have a .shp.xml file that contains metadata and two spatial index files, .sbn and .sbx. To find shapefiles, you can usually search for open data and a city name. In this example, we will be using a shapefile from ABQ Data, the City of Albuquerque data portal. You can find more data on this at http://www.cabq.gov/abq-data. When you download a shapefile, it will most likely be in the ZIP format because it will contain multiple files. To open a shapefile in Leaflet using the leaflet-shpfile plugin, follow these steps: First, add references to two JavaScript files. The first, leaflet-shpfile, is the plugin, and the second depends on the shapefile parser, shp.js: <script src="leaflet.shpfile.js"></script> <script src="shp.js"></script> Next, create a new shapefile layer and add it to the map. Pass the layer path to the zipped shapefile: var shpfile = new L.Shapefile('council.zip'); shpfile.addTo(map); Your map should display the shapefile as shown in the following screenshot: Performing the preceding steps will add the shapefile to the map. You will not be able to see any individual feature properties. When you create a shapefile layer, you specify the data, followed by specifying the options. The options are passed to the L.geoJson class. The following code shows you how to add a pop up to your shapefile layer: var shpfile = new L.Shapefile('council.zip',{onEachFeature:function(feature, layer) { layer.bindPopup("<a href='"+feature.properties.WEBPAGE+"'>Page</a><br><a href='"+feature. properties.PICTURE+"'>Image</a>"); }}); In the preceding code, you pass council.zip to the shapefile, and for options, you use the onEachFeature option, which takes a function. In this case, you use an anonymous function and bind the pop up to the layer. In the text of the pop up, you concatenate your HTML with the name of the property you want to display using the format feature.properties.NAME-OF-PROPERTY. To find the names of the properties in a shapefile, you can open .dbf and look at the column headers. However, this can be cumbersome, and you may want to add all of the shapefiles in a directory without knowing its contents. If you do not know the names of the properties for a given shapefile, the following example shows you how to get them and then display them with their value in a pop up: var holder=[]; for (var key in feature.properties){holder.push(key+": "+feature.properties[key]+"<br>");popupContent=holder.join(""); layer.bindPopup(popupContent);} shapefile.addTo(map); In the preceding code, you first create an array to hold all of the lines in your pop up, one for each key/value pair. Next, you run a for loop that iterates through the object, grabbing each key and concatenating the key name with the value and a line break. You push each line into the array and then join all of the elements into a single string. When you use the .join() method, it will separate each element of the array in the new string with a comma. You can pass empty quotes to remove the comma. Lastly, you bind the pop up with the string as the content and then add the shapefile to the map. You now have a map that looks like the following screenshot: The shapefile also takes a style option. You can pass any of the path class options, such as the color, opacity, or stroke, to change the appearance of the layer. The following code creates a red polygon with a black outline and sets it slightly transparent: var shpfile = new L.Shapefile('council.zip',{style:function(feature){return {color:"black",fillColor:"red",fillOpacity:.75}}}); Summary In this article, we learned how shapefiles can be added to a geographical map. We learned how pop ups are added to the maps. This article also showed how these pop ups would look once added to the map. You will also learn how to connect to an ESRI server that has an exposed REST service. Resources for Article: Further resources on this subject: Getting started with Leaflet [Article] Using JavaScript Effects with Joomla! [Article] Quick start [Article]
Read more
  • 0
  • 0
  • 34358

article-image-10-commandments-for-effective-ux-design
Will Grant
11 Mar 2019
8 min read
Save for later

Will Grant’s 10 commandments for effective UX Design

Will Grant
11 Mar 2019
8 min read
Somewhere along the journey of web maturity, we forgot something important: user experience is not art. It's the opposite of art. UX design should perform one primary function: serving users. Your UX design has to look great, but it should not be at the expense of hampering the working of the website. This is an extract from 101 UX Principles by Will Grant. Read our interview with Will here. #1 Empathy and objectivity are the primary skills of a  UX professional Empathy and objectivity are the primary skills you must possess to be good at UX. This is not to undermine those who have spent many years studying and working in the UX field — their insights and experience are valuable — rather say that study and practice alone are not enough. You need empathy to understand your users’ needs, goals, and frustrations. You need objectivity to look at your product with fresh eyes, spot the flaws and fix them. You can learn everything else. Read More: Soft skills every data scientist should teach their child #2 Don’t use more than two typefaces Too often designers add too many typefaces to their products. You should aim to use two typefaces maximum: one for headings and titles, and another for body copy that is intended to be read. Using too many typefaces creates too much visual ‘noise’ and increases the effort that the user has to put into understanding the view in front of them. What’s more, many custom-designed brand typefaces are made with punchy visual impact in mind, not readability. Use weights and italics within that font family for emphasis, rather than switching to another family. Typically, this means using your corporate brand font as the heading, while leaving the controls, dialogs and in-app copy (which need to be clearly legible) in a more proven, readable typeface. #3 Make your buttons look like buttons There are parts of your UI that can be interacted with, but your user doesn’t know which parts and doesn’t want to spend time learning. Flat design is bad. It’s really terrible for usability. It’s style over substance and it forces your users to think more about every interaction they make with your product. Stop making it hard for your customers to find the buttons! By drawing on real-world examples, we can make UI buttons that are obvious and instantly familiar. By using real-life inspiration to create affordances, a new user can identify the controls right away. Create the visual cues your user needs to know instantly that they’re looking at a button that can be tapped or clicked. #4 Make ‘blank slates’ more than just empty views The default behavior of many apps is to simply show an empty view where the content would be. For a new user, this is a pretty poor experience and a massive missed opportunity for you to give them some extra orientation and guidance. The blank slate is only shown once (before the user has generated any content). This makes it an ideal way of orienting people to the functions of your product while getting out of the way of more established users who will hopefully ‘know the ropes’ a little better. For that reason, it should be considered mandatory for UX designers to offer users a useful blank slate. #5 Hide ‘advanced’ settings from most users There’s no need to include every possible menu option on your menu when you can hide advanced settings away. Group settings together but separate out the more obscure ones for their own section of ‘power user’ settings. These should also be grouped into sections if there are a lot of them (don’t just throw all the advanced items in at random). Not only does hiding advanced settings have the effect of reducing the number of items for a user to mentally juggle, but it also makes the app appear less daunting, by hiding complex settings from most users. By picking good defaults, you can ensure that the vast majority of users will never need to alter advanced settings. For the ones that do, an advanced menu section is a pretty well-used pattern. #6 Use device-native input features where possible If you’re using a smartphone or tablet to dial a telephone number, the device’s built-in ‘phone’ app will have a large numeric keypad, that won’t force you to use a fiddly ‘QWERTY’ keyboard for numeric entry. Sadly, too often we ask users to use the wrong input features in our products. By leveraging what’s already there, we can turn painful form entry experiences into effortless interactions. No matter how good you are, you can’t justify spending the time and money that other companies have spent on making usable system controls. Even if you get it right, it’s still yet another UI for your user to learn, when there’s a perfectly good one already built into their device. Use that one. #7 Always give icons a text label Icons are used and misused so relentlessly, across so many products, that you can’t rely on any 'one' single icon to convey a definitive meaning. For example, if you’re offering a ‘history’ feature,  there’s a wide range of pictogram clocks, arrows, clocks within arrows, hourglasses, and parchment scrolls to choose from. This may confuse the user and hence you need to add a text label to make the user understand what this icon means in this context within your product. Often, a designer will decide to sacrifice the icon label on mobile responsive views. Don’t do this. Mobile users still need the label for context. The icon and the label will then work in tandem to provide context and instruction and offer a recall to the user, whether they’re new to your product or use it every day. #8 Decide if an interaction should be obvious, easy or possible To help decide where (and how prominently) a control or interaction should be placed, it’s useful to classify interactions into one of three types. Obvious Interactions Obvious interactions are the core function of the app, for example, the shutter button on a camera app or the “new event” button on a calendar app. Easy Interactions An easy interaction could be switching between the front-facing and rear-facing lens in a camera app, or editing an existing event in a calendar app. Possible Interactions Interactions we classify as possible are rarely used and they are often advanced features. For example, it is possible to adjust the white balance or auto-focus on a camera app or make an event recurring on a calendar app. #9 Don’t join the dark side So-called ‘dark patterns’ are UI or UX patterns designed to trick the user into doing what the corporation or brand wants them to do. These are, in a way, exactly the same as the scams used by old-time fraudsters and rogue traders, now transplanted to the web and updated for the post-internet age. Shopping carts that add extra "add-on" items (like insurance, protection policies, and so on) to your cart before you check out, hoping that you won't remove them Search results that begin their list by showing the item they'd like to sell you instead of the best result Ads that don't look like ads, so you accidentally tap them Changing a user's settings—edit your private profile and if you don't explicitly make it private again, the company will switch it back to public Unsubscribe "confirmation screens", where you have to uncheck a ton of checkboxes just right to actually unsubscribe. In some fields, medicine, for example, professionals have a code of conduct and ethics that form the core of the work they do. Building software does not have such a code of conduct, but maybe it should do. #10 Test with real users There’s a myth that user testing is expensive and time-consuming, but the reality is that even very small test groups (less than 10 people) can provide fascinating insights. The nature of such tests is very qualitative and doesn’t lend itself well to quantitative analysis, so you can learn a lot from working with a small sample set of fewer than 10 users. Read More: A UX strategy is worthless without a solid usability test plan You need to test with real users, not your colleagues, not your boss and not your partner. You need to test with a diverse mix of people, from the widest section of society you can get access to. User testing is an essential step to understanding not just your product but also the users you’re testing: what their goals really are, how they want to achieve them and where your product delivers or falls short. Summary In the web development world, UX and UI professionals keep making UX mistakes, trying to reinvent the wheel, and forgetting to put themselves in the place of a user. Following these 10 commandments and applying them to the software design will create more usable and successful products, that look great but at the same time do not hinder functionality. Is your web design responsive? What UX designers can teach Machine Learning Engineers? To start with: Model Interpretability Trends UX Design
Read more
  • 0
  • 0
  • 33959

article-image-using-native-sdks-and-libraries-react-native
Emilio Rodriguez
07 Apr 2016
6 min read
Save for later

Using Native SDKs and Libraries in React Native

Emilio Rodriguez
07 Apr 2016
6 min read
When building an app in React Native we may end up needing to use third-party SDKs or libraries. Most of the time, these are only available in their native version, and, therefore, only accessible as Objective-C or Swift libraries in the case of iOS apps or as Java Classes for Android apps. Only in a few cases these libraries are written in JavaScript and even then, they may need pieces of functionality not available in React Native such as DOM access or Node.js specific functionality. In my experience, this is one of the main reasons driving developers and IT decision makers in general to run away from React Native when considering a mobile development framework for their production apps. The creators of React Native were fully aware of this potential pitfall and left a door open in the framework to make sure integrating third-party software was not only possible but also quick, powerful, and doable by any non-iOS/Android native developer (i.e. most of the React Native developers). As a JavaScript developer, having to write Objective-C or Java code may not be very appealing in the beginning, but once you realize the whole process of integrating a native SDK can take as little as eight lines of code split in two files (one header file and one implementation file), the fear quickly fades away and the feeling of being able to perform even the most complex task in a mobile app starts to take over. Suddenly, the whole power of iOS and Android can be at any React developer’s disposal. To better illustrate how to integrate a third-party SDK we will use one of the easiest to integrate payment providers: Paymill. If we take a look at their site, we notice that only iOS and Android SDKs are available for mobile payments. That should leave out every app written in React Native if it wasn’t for the ability of this framework to communicate with native modules. For the sake of convenience I will focus this article on the iOS module. Step 1: Create two native files for our bridge. We need to create an Objective-C class, which will serve as a bridge between our React code and Paymill’s native SDK. Normally, an Objective-C class is made out of two files, a .m and a .h, holding the module implementation and the header for this module respectively. To create the .h file we can right-click on our project’s main folder in XCode > New File > Header file. In our case, I will call this file PaymillBridge.h. For React Native to communicate with our bridge, we need to make it implement the RTCBridgeModule included in React Native. To do so, we only have to make sure our .h file looks like this: // PaymillBridge.h #import "RCTBridgeModule.h" @interface PaymillBridge : NSObject <RCTBridgeModule> @end We can follow a similar process to create the .m file: Right-click our project’s main folder in XCode > New File > Objective-C file. The module implementation file should include the RCT_EXPORT_MODULE macro (also provided in any React Native project): // PaymillBridge.m @implementation PaymillBridge RCT_EXPORT_MODULE(); @end A macro is just a predefined piece of functionality that can be imported just by calling it. This will make sure React is aware of this module and would make it available for importing in your app. Now we need to expose the method we need in order to use Paymill’s services from our JavaScript code. For this example we will be using Paymill’s method to generate a token representing a credit card based on a public key and some credit card details: generateTokenWithPublicKey. To do so, we need to use another macro provided by React Native: RCT_EXPORT_METHOD. // PaymillBridge.m @implementation PaymillBridge RCT_EXPORT_MODULE(); RCT_EXPORT_METHOD(generateTokenWithPublicKey: (NSString *)publicKey cardDetails:(NSDictionary *)cardDetails callback:(RCTResponseSenderBlock)callback) { //… Implement the call as described in the SDK’s documentation … callback(@[[NSNull null], token]); } @end In this step we will have to write some Objective-C but most likely it would be a very simple piece of code using the examples stated in the SDK’s documentation. One interesting point is how to send data from the native SDK to our React code. To do so you need to pass a callback as you can see I did as the last parameter of our exported method. Callbacks in React Native’s bridges have to be defined as RCTResponseSenderBlock. Once we do this, we can call this callback passing an array of parameters, which will be sent as parameters for our JavaScript function in React Native (in our case we decided to pass two parameters back: an error set to null following the error handling conventions of node.js, and the token generated by Paymill natively). Step 2: Call our bridge from our React Native code. Once the module is properly set up, React Native makes it available in our app just by importing it from our JavaScript code: // PaymentComponent.js var Paymill = require('react-native').NativeModules.PaymillBridge; Paymill.generateTokenWithPublicKey( '56s4ad6a5s4sd5a6', cardDetails, function(error, token){ console.log(token); }); NativeModules holds the list of modules we created implementing the RCTBridgeModule. React Native makes them available by the name we chose for our Objective-C class name (PaymillBridge in our example). Then, we can call any exported native method as a normal JavaScript method from our React Native Component or library. Going Even Further That should do it for any basic SDK, but React Native gives developers a lot more control on how to communicate with native modules. For example, we may want to force the module to be run in the main thread. For that we just need to add an extra method to our native module implementation: // PaymillBridge.m @implementation PaymillBridge //... - (dispatch_queue_t)methodQueue { return dispatch_get_main_queue(); } Just by adding this method to our PaymillBridge.m React Native will force all the functionality related to this module to be run on the main thread, which will be needed when running main-thread-only iOS API. And there is more: promises, exporting constants, sending events to JavaScript, etc. More complex functionality can be found in the official documentation of React Native; the topics covered on this article, however, should solve 80 percent of the cases when implementing most of the third-party SDKs. About the Author Emilio Rodriguez started working as a software engineer for Sun Microsystems in 2006. Since then, he has focused his efforts on building a number of mobile apps with React Native while contributing to the React Native project. These contributions helped his understand how deep and powerful this framework is.
Read more
  • 0
  • 2
  • 33600

article-image-react-conf-2019-concurrent-mode-preview-out-css-in-js-react-docs-in-40-languages-and-more
Bhagyashree R
29 Oct 2019
9 min read
Save for later

React Conf 2019: Concurrent Mode preview out, CSS-in-JS, React docs in 40 languages, and more

Bhagyashree R
29 Oct 2019
9 min read
React Conf 2019 wrapped up last week. It was kick-started with a keynote by Tom Occhino and Yuhi Zheng from the React team who both talked about Concurrent Mode and Suspense. Then followed by Frank Yan also from the React team, who explained how they are building the “new Facebook” with React and Relay. One of the major highlights of his talk was the CSS-in-JS library that will be open-sourced once ready. Sophie Alpert, former manager of the React team gave a talk on building a custom React renderer. To demonstrate that, she implemented a small version of ReactDOM in just 30 minutes. There were many other lightning talks and presentations on translated React, building inclusive apps by improving their accessibility, and much more. React Conf 2019 is a two-day event that took place from Oct 24-25 at Lake Las Vegas, Nevada. This conference brought together front-end and full-stack developers to “share knowledge, skills, to network, and just to have fun.” React's long-term goal: "Making it easier to build great user experiences" Tom Occhino, Engineering Director of the React group, took to the stage to talk about the goals for React and the community. He says that React’s long-term goal is to make it easier for developers to build great user experiences. “Easier to build” means improving the developer experience. The three factors that contribute to a great developer experience are a low barrier to entry, developer productivity, and ability to scale. React is constantly working towards improving the developer experience by introducing new features. Two such features are: Concurrent Mode and Suspense. Concurrent Mode Concurrent Mode is a set of features to make React apps more responsive by rendering component trees without blocking the main thread. It gives React the ability to interrupt big blocks of low-priority work in order to focus on higher priority work like responding to user input. This will enable React to work on several state updates concurrently and removing jarring and too frequent DOM updates. The team also released the first early community preview of Concurrent Mode last week. https://twitter.com/reactjs/status/1187411505001746432 Suspense Suspense was introduced as an improvement to the developer experience when dealing with asynchronous data fetching within React apps. It suspends your component rendering and shows a fallback until some condition is met. Occhino describes Suspense as a “React system for orchestrating asynchronous loading of code, data, and resources.” He adds, “Suspense lets the component wait for something before they render. This helps consolidate nested dependencies and nested spinners and things behind the single simple loading experience.” Towards the end of his keynote, Occhino also touched upon how the team plans to make the React community more inclusive and diverse. He said, “Over the past 10 years, I have learned that diverse teams build better products and make better decisions. Everyone working on React shares my conviction about this.” He adds, “Up until recently we have taken a pretty passive stance to building and shaping the React community. We have a responsibility to you all and I feel like we let many of you down. We are committed to doing better!” As a first step, the team has now replaced the React code of conduct with the contributor covenant. Read also: #Reactgate forces React leaders to confront community’s toxic culture head on What’s new the React team is working on Yuzi Zheng, Engineering Manager for React and Relay team at Facebook gave an insight into what projects the core teams are working on. She started off by giving a recap of hooks, which was one of the most-awaited React features announced at React Conf 2018. “Hooks are designed for the future of React in the way that it naturally encourages code that is compatible with all the plumbing features such as accessibility, server-side rendering, suspense, and concurrent mode. Since its release, the reception of Hooks has been really positive,” she shared. If you want to understand the fundamentals of React Hooks and use them for implementing responsive design and more, check out our book, Learning Hooks. Another long-term project that the team is focusing on is providing developers a way to easily build accessibility features in React. Currently, developers can create accessible websites using standard HTML techniques, but it does have some limitations. To help building accessibility directly into React the team is working on two areas: managing focus and input interfaces. For managing focus, the team plans to add primitives that provide “a more structured way of making sure component flows well” for cases like React portals and Suspense fallback and are accessible by default. For input interfaces, they plan to add support for rich gestures that work across platforms and are accessible by default. The team is also focusing on improving the initial render times. Server-side rendering helps in reducing the amount of CPU usage on the client for the initial render to some extent, but it does have some limitations. To meet these limitations, the team plans to add built-in support for server-side rendering. This will work with lazily loaded components to reduce the bytes needed on the client, support streaming down markups in chunks, and be fully-compatible with Concurrent Mode and Suspense. The CSS-in-JS library Frank Yan, Engineering Manager in the React group at Facebook talked about how the team has rebuilt and redesigned the Facebook website and the key lessons they have learned along the way. The new Facebook website is a single-page app with React organizing the HTML and JavaScript into components from the top down and with GraphQL and Relay colocating the queries declaratively in the components. The only key part that the team did not reorganize was CSS. They instead created a new library to embed styles in components called CSS-in-JS. It aims to make the styles easier to read, understand, and update. Its syntax is inspired by React Native and other frameworks. Since it enables you to embed styles inside JavaScript files, you can also use JavaScript tooling like type checkers and linters. React docs translated into 40 languages Nat Alison is a freelance front-end developer who helped the React team coordinate translations of reactjs.org into 40 languages. She shared why and how they were able to translate the docs for this massively popular library. She shared, “More than 80% of the world’s population does not know English. If we restrict React, one of the most popular JavaScript frameworks, we restrict who gets to create and shape the web.” Providing the officially translated docs will make it easier for several non-English speaking React developers to understand and use it in their projects. This will also prevent users from creating unofficial translations, which can be incorrect, outdated, or difficult to find. Initially, they thought of integrating a SaaS platform that allows users to submit translations, but this was not a feasible solution. Then they decided to check out the solution used by Vue, which is maintaining separate repositories for each language forked from the original repo. Similar to Vue, the team also created a bot that periodically tracks for changes in the English repo and submits pull requests whenever there is a change. If you want to contribute to translating React docs in your language, check out the IsReactTranslatedYet website. Developing accessible apps Brittany Feenstra, a developer at Formidable, took to the stage to talk about why accessibility is important and how you can approach it. Accessibility or a11y is making your apps and websites usable for everyone, including people with any kind of disabilities.  There are four types of disabilities that developers need to design for: visual, auditory, motor, and cognitive. Feenstra mentioned that though we all are aware of the importance of accessibility, we often “end up saving it for later” because of tight deadlines. Feenstra, however, compares accessibility with marathons. It is not something that you can achieve in just one sprint, she says. You should instead look at it as a training program that you will follow when participating in a marathon. You need to take a step-by-step approach to make an accessible app. If we do that “we will be way less fatigued and well-equipped,” she adds. Sharing some starting tips she said that we need to focus on three areas. First, learn to run, or in accessibility context, understand the HTML semantics then explore reference patterns, navigation, and focus traps. Second, improve nutritional habits, or in accessibility context, use environments and tools that help us write sturdier code. She recommends using axe, an accessibility checker for WCAG 2 and Section 508 accessibility. Also, check out the tools that basically simulate how people with visual impairment will see your UI such as NoCoffee and I want to see like the colour blind. She emphasizes on linting and testing your code for accessibility with the help of eslint-plugin-jsx-a11y and accessibility assessment automation tools. Third, cross-train and stretch, or in accessibility context, learn to “interact with the UI in ways that let us understand the update we are making to our code.” “React is Fiction” This was a talk by Jenn Creighton, a Frontend Architect at The Wing, who comes from a creative writing background. “Writing React to me felt like coming home. It was really familiar in a way that I could not pinpoint,” she said. Then she realized that writing React reminded her of fiction and merging the two disciplines helped her write better components. Creighton drew the similarities between developing in React and creative writing. One of the key principles of creative writing is “Show, don’t tell” that advises authors to describe a situation instead of just telling it. This will help engage the readers as they will be able to picture the situation in their heads. According to Creighton, React also has a similar principle: “Declarative, not imperative.”  React is declarative, which allows developers to describe what the final state should be, instead of listing all the steps to reach that state. There were many other exciting talks about progressive web animations, building React-Select, and more. Check out the live streams to watch the full talks: Day1: https://www.youtube.com/watch?v=RCiccdQObpo Day2: https://www.youtube.com/watch?v=JDDxR1a15Yo&t=2376s Ionic React released; Ionic Framework pivots from Angular to a native React version ReactOS 0.4.12 releases with kernel improvements, Intel e1000 NIC driver support, and more React Native 0.61 introduces Fast Refresh for reliable hot reloading
Read more
  • 0
  • 0
  • 33307
Unlock access to the largest independent learning library in Tech for FREE!
Get unlimited access to 7500+ expert-authored eBooks and video courses covering every tech area you can think of.
Renews at $19.99/month. Cancel anytime
article-image-introducing-r-rstudio-and-shiny
Packt
25 Sep 2015
9 min read
Save for later

Introducing R, RStudio, and Shiny

Packt
25 Sep 2015
9 min read
 In this article, by Hernán G. Resnizky, author of the book Learning Shiny, the main objective will be to learn how to install all the needed components to build an application in R with Shiny. Additionally, some general ideas about what R is will be covered in order to be able to dive deeper into programming using R. The following topics will be covered: A brief introduction to R, RStudio, and Shiny Installation of R and Shiny General tips and tricks (For more resources related to this topic, see here.) About R As stated on the R-project main website: "R is a language and environment for statistical computing and graphics." R is a successor of S and is a GNU project. This means, briefly, that anyone can have access to its source codes and can modify or adapt it to their needs. Nowadays, it is gaining territory over classic commercial software, and it is, along with Python, the most used language for statistics and data science. Regarding R's main characteristics, the following can be considered: Object oriented: R is a language that is composed mainly of objects and functions. Can be easily contributed to: Similar to GNU projects, R is constantly being enriched by user's contributions either by making their codes accessible via "packages" or libraries, or by editing/improving its source code. There are actually almost 7000 packages in the common R repository, Comprehensive R Archive Network (CRAN). Additionally, there are R repositories of public access, such as bioconductor project that contains packages for bioinformatics. Runtime execution: Unlike C or Java, R does not need compilation. This means that you can, for instance, write 2 + 2 in the console and it will return the value. Extensibility: The R functionalities can be extended through the installation of packages and libraries. Standard proven libraries can be found in CRAN repositories and are accessible directly from R by typing install.packages(). Installing R R can be installed in every operating system. It is highly recommended to download the program directly from http://cran.rstudio.com/ when working on Windows or Mac OS. On Ubuntu, R can be easily installed from the terminal as follows: sudo apt-get update sudo apt-get install r-base sudo apt-get install r-base-dev The installation of r-base-dev is highly recommended as it is a package that enables users to compile the R packages from source, that is, maintain the packages or install additional R packages directly from the R console using the install.packages() command. To install R on other UNIX-based operating systems, visit the following links: http://cran.rstudio.com/ http://cran.r-project.org/doc/manuals/r-release/R-admin.html#Obtaining-R A quick guide to R When working on Windows, R can be launched via its application. After the installation, it is available as any other program on Windows. When opening the program, a window like this will appear: When working on Linux, you can access the R console directly by typing R on the command line: In both the cases, R executes in runtime. This means that you can type in code, press Enter, and the result will be given immediately as follows: > 2+2 [1] 4 The R application in any operating system does not provide an easy environment to develop code. For this reason, it is highly recommended (not only to write web applications in R with Shiny, but for any task you want to perform in R) to use an Integrated Development Environment (IDE). About RStudio As with other programming languages, there is a huge variety of IDEs available for R. IDEs are applications that make code development easier and clearer for the programmer. RStudio is one of the most important ones for R, and it is especially recommended to write web applications in R with Shiny because this contains features specially designed for R. Additionally, RStudio provides facilities to write C++, Latex, or HTML documents and also integrates them to the R code. RStudio also provides version control, project management, and debugging features among many others. Installing RStudio RStudio for desktop computers can be downloaded from its official website at http://www.rstudio.com/products/rstudio/download/ where you can get versions of the software for Windows, MAC OS X, Ubuntu, Debian, and Fedora. Quick guide to RStudio Before installing and running RStudio, it is important to have R installed. As it is an IDE and not the programming language, it will not work at all. The following screenshot shows RStudio's starting view: At the first glance, the following four main windows are available: Text editor: This provides facilities to write the R scripts such as highlighting and a code completer (when hitting Tab, you can see the available options to complete the code written). It is also possible to include the R code in an HTML, Latex, or C++ piece of code. Environment and history: They are defined as follows: In the Environment section, you can see the active objects in each environment. By clicking on Global Environment (which is the environment shown by default), you can change the environment and see the active objects. In the History tab, the pieces of codes executed are stored line by line. You can select one or more lines and send them either to the editor or to the console. In addition, you can look up for a certain specific piece of code by typing it in the textbox in the top right part of this window. Console: This is an exact equivalent of R console, as described in Quick guide of R. Tabs: The different tabs are defined as follows: Files: This consists of a file browser with several additional features (renaming, deleting, and copying). Clicking on a file will open it in editor or the Environment tab depending on the type of the file. If it is a .rda or .RData file, it will open in both. If it is a text file, it will open in one of them. Plots: Whenever a plot is executed, it will be displayed in that tab. Packages: This shows a list of available and active packages. When the package is active, it will appear as clicked. Packages can also be installed interactively by clicking on Install Packages. Help: This is a window to seek and read active packages' documentation. Viewer: This enables us to see the HTML-generated content within RStudio. Along with numerous features, RStudio also provides keyboard shortcuts. A few of them are listed as follows: Description Windows/Linux OSX Complete the code. Tab Tab Run the selected piece of code. If no piece of code is selected, the active line is run. Ctrl + Enter ⌘ + Enter Comment the selected block of code. Ctrl + Shift + C ⌘ + / Create a section of code, which can be expanded or compressed by clicking on the arrow to the left. Additionally, it can be accessed by clicking on it in the bottom left menu. ##### ##### Find and replace. Ctrl + F ⌘ + F The following screenshots show how a block of code can be collapsed by clicking on the arrow and how it can be accessed quickly by clicking on its name in the bottom-left part of the window: Clicking on the circled arrow will collapse the Section 1 block, as follows: The full list of shortcuts can be found at https://support.rstudio.com/hc/en-us/articles/200711853-Keyboard-Shortcuts. For further information about other RStudio features, the full documentation is available at https://support.rstudio.com/hc/en-us/categories/200035113-Documentation. About Shiny Shiny is a package created by RStudio, which enables to easily interface R with a web browser. As stated in its official documentation, Shiny is a web application framework for R that makes it incredibly easy to build interactive web applications with R. One of its main advantages is that there is no need to combine R code with HTML/JavaScript code as the framework already contains prebuilt features that cover the most commonly used functionalities in a web interactive application. There is a wide range of software that has web application functionalities, especially oriented to interactive data visualization. What are the advantages of using R/Shiny then, you ask? They are as follows: It is free not only in terms of money, but as all GNU projects, in terms of freedom. As stated in the GNU main page: To understand the concept (GNU), you should think of free as in free speech, not as in free beer. Free software is a matter of the users' freedom to run, copy, distribute, study, change, and improve the software. All the possibilities of a powerful language such as R is available. Thanks to its contributive essence, you can develop a web application that can display any R-generated output. This means that you can, for instance, run complex statistical models and return the output in a friendly way in the browser, obtain and integrate data from the various sources and formats (for instance, SQL, XML, JSON, and so on) the way you need, and subset, process, and dynamically aggregate the data the way you want. These options are not available (or are much more difficult to accomplish) under most of the commercial BI tools. Installing and loading Shiny As with any other package available in the CRAN repositories, the easiest way to install Shiny is by executing install.packages("shiny"). The following output should appear on the console: Due to R's extensibility, many of its packages use elements (mostly functions) from other packages. For this reason, these packages are loaded or installed when the package that is dependent on them is loaded or installed. This is called dependency. Shiny (on its 0.10.2.1 version) depends on Rcpp, httpuv, mime, htmltools, and R6. An R session is started only with the minimal packages loaded. So if functions from other packages are used, they need to be loaded before using them. The corresponding command for this is as follows: library(shiny) When installing a package, the package name must be quoted but when loading the package, it must be unquoted. Summary After these instructions, the reader should be able to install all the fundamental elements to create a web application with Shiny. Additionally, he or she must have acquired at least a general idea of what R and the R project is. Resources for Article: Further resources on this subject: R ─ Classification and Regression Trees[article] An overview of common machine learning tasks[article] Taking Control of Reactivity, Inputs, and Outputs [article]
Read more
  • 0
  • 0
  • 33103

article-image-web-development-react-and-bootstrap
Packt
04 Jan 2017
18 min read
Save for later

Web Development with React and Bootstrap

Packt
04 Jan 2017
18 min read
In this article by Harmeet Singh and Mehul Bhat, the authors of the book Learning Web Development with React and Bootstrap, we are going to see how we can build responsive web applications with the help of Bootstrap and ReactJS. (For more resources related to this topic, see here.) There are many different ways to build modern web applications with JavaScript and CSS, including a lot of different tool choices, and a lot of new theory to learn. This book introduces you to ReactJS and Bootstrap which you will likely come across as you learn about modern web app development. They both are used for building fast and scalable user interfaces. React is famously known as a view (V) in MVC when we talk about defining M and C we need to look somewhere else or we can use other frameworks like Redux and Flux to handle remote data. The best way to learn code is to write code, so we're going to jump right in. To show you just how easy it is to get up and running with Bootstrap and ReactJS, we're going to cover theory and will see how we can make super simple applications as well as integrate with other applications. ReactJS React (sometimes styled React.js or ReactJS) is an open-source JavaScript library which provides a view for data rendered as HTML. Components have been used typically to render React views which contain additional components specified as custom HTML tags. React gives you a trivial virtual DOM, powerful views without templates, unidirectional data flow and explicit mutation. It is very methodical in updating the HTML document when data changes; and a clean separation between components on a modern single-page application. As your app comes into existence and develops, it's advantageous to ensure that your components are used in the right manner and the React app consists of reusable components, which makes code reuse, testing, and separation of concerns easy. React is not only V in MVC, it has stateful components, it handles mapping from input to state changes, and it renders components. In this sense, it does everything that an MVC would do. Let's look at React's component life cycle and it's different levels: Bootstrap Bootstrap is an open source frontend framework maintained by Twitter for developing responsive websites and web applications. It includes HTML, CSS, and JavaScript code to build user interface components. It's a faster and an easier way to develop powerful mobile-first user interface. Bootstrap grid system allows us to create responsive 12 column grids, layout, and components. It includes predefined classes for easy layout options (fixed width and full width). Bootstrap have pre-styled dozen reusable components and custom jQuery plugins like button, alerts, dropdown, modal, tooltip tab, pagination, carousal, badges, icons and many more. Bootstrap package includes the compiled and minified version of CSS and JS for our app we just need CSS bootstrap.min.css and fonts folder. This style sheet will provide you the look and feel of all components, responsive layout structure for our application. In the previous version Bootstrap included icons as image but in version 3 they have replaced icons as fonts. We can also customize the Bootstrap CSS stylesheet as per the component featured in our application. React-Bootstrap The React-Bootstrap JavaScript framework is similar to Bootstrap rebuilt for React. It's a complete reimplementation of the Bootstrap frontend reusable components in React. React-Bootstrap has no dependency on any other framework, such as Bootstrap.js or jQuery. It means that if you are using React-Bootstrap then we don't need to include the jQuery in your project as a dependency. Using React-Bootstrap, we can be sure that, there won't be external JavaScript calls to render the component which might be incompatible with the React DOM render. However, you can still achieve the same functionality and look and feel as Twitter Bootstrap, but with much cleaner code. Benefits of React-Bootstrap Compare to Twitter Bootstrap, we can import required code/component. It saves a bit of typing and bugs by compressing the Bootstrap. It reduces typing efforts and, more importantly, conflicts by compressing the Bootstrap. We don't need to think about the different approaches taken by Bootstrap versus. React It is easy to use It encapsulates in elements It uses JSX syntax It avoids React rendering of the virtual DOM It is easy to detect DOM changes and update the DOM without any conflict It doesn't have any dependency on other libraries, such as jQuery Bootstrap grid system Bootstrap is based on a 12-column grid system which includes a powerful responsive structure and a mobile-first fluid grid system that allows us to scaffold our web app with very few elements. In Bootstrap, we have a predefined series of classes to compose of rows and columns, so before we start we need to include the <div>tag with the container class to wrap our rows and columns. Otherwise, the framework won't respond as expected because Bootstrap has written CSS which is dependent on it. The preceding snippet has HTML structure of container class <div> tag: <div class="container"><div> This will make your web app the centre of the page as well as control the rows and columns to work as expected in responsive. There are four class prefixes which help to define the behaviour of the columns. All the classes are related to different device screen sizes and react in familiar ways. The following table from http://getbootstrap.com defines the variations between all four classes:   Extra small devices Phones (<768px) Small devices Tablets (≥768px) Medium devices Desktops (≥992px) Large devices Desktops (≥1200px) Grid behavior Horizontal at all times Collapsed to start, horizontal above breakpoints Container width None (auto) 750px 970px 1170px Class prefix .col-xs- .col-sm- .col-md- .col-lg- # of columns 12 Column width Auto ~62px ~81px ~97px Gutter width 30px (15px on each side of a column) Nestable Yes Offsets Yes Column ordering Yes React components React is basically based on a modular build, with encapsulated components that manage their own state so it will efficiently update and render your components when data changes. In React, components logic is written in JavaScript instead of templates so you can easily pass rich data through your app and manage the state out of the DOM. Using the render() method, we are rendering a component in React that takes input data and returns what you want to display. It can either take HTML tags (strings) or React components (classes). Let's take a quick look at examples of both: var myReactElement = <div className="hello" />; ReactDOM.render(myReactElement, document.getElementById('example')); In this example, we are passing HTML as a string into the render method which we have used before creating the <Navbar>: var ReactComponent = React.createClass({/*...*/}); var myReactElement = <ReactComponent someProperty={true} />; ReactDOM.render(myReactElement, document.getElementById('example')); In the preceding example, we are rendering the component, just to create a local variable that starts with an uppercase convention. Using the upper versus lowercase convention in React's JSX will distinguish between local component classes and HTML tags. So, we can create our React elements or components in two ways: either we can use Plain JavaScript with React.createElement or React's JSX. React.createElement() Using JSX in React is completely optional for creating the react app. As we know, we can create elements with React.createElement which take three arguments: a tag name or component, a properties object, and a variable number of child elements, which is optional: var profile = React.createElement('li',{className:'list-group-item'}, 'Profile'); var profileImageLink = React.createElement('a',{className:'center-block text-center',href:'#'},'Image'); var profileImageWrapper = React.createElement('li',{className:'list-group-item'}, profileImageLink); var sidebar = React.createElement('ul', { className: 'list-group' }, profile, profileImageWrapper); ReactDOM.render(sidebar, document.getElementById('sidebar')); In the preceding example, we have used React.createElement to generate a ulli structure. React already has built-in factories for common DOM HTML tags. JSX in React JSX is extension of JavaScript syntax and if you observe the syntax or structure of JSX, you will find it similar to XML coding. JSX is doing preprocessor footstep which adds XML syntax to JavaScript. Though, you can certainly use React without JSX but JSX makes react a lot more neat and elegant. Similar like XML, JSX tags are having tag name, attributes, and children and in that if an attribute value is enclosed in quotes that value becomes a string. The way XML is working with balanced opening and closing tags, JSX works similarly and it also helps to understand and read huge amount of structures easily than JavaScript functions and objects. Advantages of using JSX in React Take a look at the following points: JSX is very simple to understand and think about than JavaScript functions Mark-up of JSX would be more familiar to non-programmers Using JSX, your markup becomes more semantic, organized, and significant JSX – acquaintance or understanding In the development region, user interface developer, user experience designer, and quality assurance people are not much familiar with any programming language but JSX makes their life easy by providing easy syntax structure which is visually similar to HTML structure. JSX shows a path to indicate and see through your mind's eye, the structure in a solid and concise way. JSX – semantics/structured syntax Till now, we have seen how JSX syntax is easy to understand and visualize, behind this there is big reason of having semantic syntax structure. JSX with pleasure converts your JavaScript code into more standard way, which gives clarity to set your semantic syntax and significance component. With the help of JSX syntax you can declare structure of your custom component with information the way you do in HTML syntax and that will do all magic to transform your syntax to JavaScript functions. ReactDOM namespace helps us to use all HTML elements with the help of ReactJS, isn't this an amazing feature! It is. Moreover, the good part is, you can write your own named components with help of ReactDOM namespace. Please check out below HTML simple mark-up and how JSX component helps you to have semantic markup. <div className="divider"> <h2>Questions</h2><hr /> </div> As you can see in the preceding example, we have wrapped <h2>Questions</h2><hr /> with <div> tag which has classNamedivider so, in React composite component, you can create similar structure and it is as easy as you do your HTML coding with semantic syntax: <Divider> Questions </Divider> Composite component As we know that, you can create your custom component with JSX markup and JSX syntax will transform your component to JavaScript syntax component. Namespace components It's another feature request which is available in React JSX. We know that JSX is just an extension of JavaScript syntax and it also provides ability to use namespace so, React is also using JSX namespace pattern rather than XML namespacing. By using, standard JavaScript syntax approach which is object property access, this feature is useful for assigning component directly as <Namespace.Component/> instead of assigning variables to access components which are stored in an object. JSXTransformer JSXTransformer is another tool to compile JSX in the browser. While reading a code, browser will read attribute type="text/jsx" in your mentioned <script> tag and it will only transform those scripts which has mentioned type attribute and then it will execute your script or written function in that file. The code will be executed in same manner the way React-tools executes on the server. JSXTransformer is deprecating in current version of React, but you can find the current version on any provided CDNs and Bower. As per my opinion, it would be great to use Babel REPL tool to compile JavaScript. It has already adopted by React and broader JavaScript community. Attribute expressions If you can see above example of show/Hide we have used attribute expression for show the message panel and hide it. In react, there is a bit change in writing an attribute value, in JavaScript expression we write attribute in quotes ("") but we have to provide pair of curly braces ({}). var showhideToggle = this.state.collapse ? (<MessagePanel>):null/>; Boolean attributes As in Boolean attribute, there are two values, either it can be true or false and if we neglect its value in JSX while declaring attribute, it by default takes value as true. If we want to have attribute value false then we have to use an attribute expression. This scenario can come regularly when we use HTML form elements, for example disabled attribute, required attribute, checked attribute, and readOnly attribute. In Bootstrap example: aria-haspopup="true"aria-expanded="true" // example of writing disabled attribute in JSX <input type="button" disabled />; <input type="button" disabled={true} />; JavaScript expressions As seen in the preceding example, you can embed JavaScript expressions in JSX using syntax that will be accustomed to any handlebars user, for example style = { displayStyle } allocates the value of the JavaScript variable displayStyle to the element's style attribute. Styles Same as the expression, you can set styles by assigning an ordinary JavaScript object to the style attribute. How interesting, if someone tells you, not to write CSS syntax but you can write JavaScript code to achieve the same, no extra efforts. Isn't it superb stuff! Yes, it is. Events There is a set of event handlers that you can bind in a way that should look much acquainted to anybody who knows HTML. Generally, as per our practice we set properties on to the object which is anti-pattern in JSX attribute standard. var component = <Component />; component.props.foo = x; // bad component.props.bar = y; // also bad As shown in the preceding example, you can see the anti-pattern and it's not the best practice. If you don't know about properties of JSX attributes then propTypes won't be set and it will throw errors which would be difficult for you to trace. Props is very sensitive part of attribute so, you should not change it, as each props is having predefined method and you should use it as it is meant for, like we use other JavaScript methods or HTML tags. This doesn't mean that it is impossible to change Props, it is possible but it is against standard defined by React. Even in React, it will throw error. Spread attributes Let's check out JSX feature—spread attributes: var props = {}; props.foo = x; props.bar = y; var component = <Component {...props} />; As you see in above example, your properties which you have declared have become part of your component's props as well. Reusability of attributes is also possible here and you can also map it with other attributes. But you have to be very careful in ordering your attributes while you declare it, as it will override the previous declared attribute with lastly declared one. Props and state React components translate your raw data into Rich HTML, the props and state together build with that raw data to keep your UI consistent. Ok, let's identify what exactly it is: Props and state are both plain JS objects. It triggers with a render update. React manage the component state by calling setState (data, callback). This method will merge data into this.state, and re-renders the component to keep our UI up to date. For example, the state of the drop-down menu (visible or hidden). React component props - short for "properties" that don't change over time. For example, drop-down menu items. Sometimes components only take some data with this .props method and render it, which makes your component stateless. Using props and state together helps you to make an interactive app. Component life cycle methods In React each component has its own specific callback function. These callback's functions play an important role when we are thinking about DOM manipulation or integrating other plugins in React (jQuery). Let's look at some commonly used methods in the lifecycle of a component: getInitialState(): This method will help you to get the initial state of a component. componentDidMount: This method is called automatically when a component is rendered or mounted for the first time in DOM. Integrate JavaScript frameworks, we'll use this method to perform operations like setTimeout or setInterval, or send AJAX requests. componentWillReceiveProps: This method will be used to receive a new props. componentWillUnmount: This method is invoked before component is unmounted from DOM. Cleanup the DOM memory elements which are mounted in componentDidMount method. componentWillUpdate: This method invoked before updating a new props and state. componentDidUpdate: This is invoked immediately when the component has been updated in DOM What is Redux? As we know, in single page applications (SPAs) when we have to contract with state and time, it would be difficult to handgrip state over time. Here, Redux helps a lot, how? Because, in JavaScript application, Redux is handling two states: one is Data state and another is UI state and it's standard option for SPAs (single page applications). Moreover, bearing in mind, Redux can be used with AngularJS or jQuery or React JavaScript libraries or frameworks. Now we know, what does Redux mean? In short, Redux is a helping hand to play with states while developing JavaScript applications. We have seen in our previous examples like, the data flows in one direction only from parent level to child level and it is known as "unidirectional data flow". React has same flow direction from data to components so in this case it would be very difficult for proper communication of two components in React. Redux's architecture benefits: Compare to other frameworks, it has more benefits: It might not have any other way effects As we know, binning is not needed because components cant not interact directly States are managed globally so less possibility of mismanagement Sometimes, for middleware it would be difficult to manage other way effects React Top Level API When we are talking about React API, it's the starting step to get into React library. Different usage of React will provide different output like using React script tag will make top-level APIs available on the React global, using ES6 with npm will allow us to write import React from 'react' and using ES5 with npm will allow us to write var React = require('react'), so there are multiple ways to intialize the React with different features. Mount/Unmount component Always, it's recommended to have custom wrapper API in your API, suppose we have single root or more than one root and it will be deleted at some period, so you will not lose it. Facebook is also having the similar set up which automatically calls unmountComponentAtNode. I also suggest not to call ReactDOM.render() every time but ideal way is to write or use it through library so, by that way Application will have mounting and unmounting to manage it. Creating custom wrapper will help you to manage configuration at one place like internationalization, routers, user data and it would be very painful to set up all configuration every time at different places. React integration with other APIs React integration is nothing but converting Web component to React component by using JSX, Redux, and other methods of React. I would like to share here, some of the best practices to be followed to have 100% quality output. Things to remember while creating application with React Take a look at the following points to remember: Before you start working on React, always remember that it is just a View library, not the MVC framework. It is advisable to have small length of component to deal with classes and modules as well as it makes life easy while code understanding, unit testing and long run maintenance of component. React has introduced functions of props in its 0.14 version which is recommended to use, it is also known as functional component which helps to split your component. To avoid painful journey while dealing with React-based app, please don't use much states. As I said earlier that React is only view library so, to deal with rendering part, I recommend to use Redux rather than other frameworks of Flux. If you want to have more type safety then always use propTypes which also helps to catch bug early and acts as a document. I recommend use of shallow rendering method to test React component which allows rendering single component without touching their child components. While dealing with large React applications, always use Webpack, NPM, ES6, JSX, and Babel to complete your application. If you want to have deep dive into React's application and its elements, you can use Reduxdev tools. Summary To begin with, we saw just how easy it is to get ReactJS and Bootstrap installed with the inclusion of JavaScript files and a style sheet. With Bootstrap, we work towards having a responsive grid system for different mobile devices and applied the fundamental styles of HTML elements with the inclusion of a few classes and divs. We also saw the framework's new mobile-first responsive design in action without cluttering up our markup with unnecessary classes or elements. Resources for Article: Further resources on this subject: Getting Started with React and Bootstrap [article] Getting Started with ASP.NET Core and Bootstrap 4 [article] Frontend development with Bootstrap 4 [article]
Read more
  • 0
  • 0
  • 32341

article-image-web-scraping-electron
Dylan Frankland
23 Dec 2016
12 min read
Save for later

Web Scraping with Electron

Dylan Frankland
23 Dec 2016
12 min read
Web scraping is a necessary evil that takes unordered information from the Web and transforms it into something that can be used programmatically. The first big use of this was indexing websites for use in search engines like Google. Whether you like it or not, there will likely be a time in your life, career, academia, or personal projects where you will need to pull information that has no API or easy way to digest programatically. The simplest way to accomplish this is to do something along the lines of a curl request and then RegEx for the necessary information. That has been what the standard procedure for much of the history of web scraping until the single-page application came along. With the advent of Ajax, JavaScript became the mainstay of the Web and prevented much of it from being scraped with traditional methods such as curl that could only get static server rendered content. This is where Electron truly comes into play because it is a full-fledged browser but can be run programmatically. Electron's Advantages Electron goes beyond the abilities of other programmatic browser solutions: PhantomJS, SlimerJS, or Selenium. This is because Electron is more than just a headless browser or automation framework. PhantomJS (and by extension SlimerJS), run headlessly only preventing most debugging and because they have their own JavaScript engines, they are not 100% compatible with node and npm. Selenium, used for automating other browsers, can be a bit of a pain to set up because it requires setting up a central server and separately installing a browser you would like to scrape with. On the other hand, Electron can do all the above and more which makes it much easier to setup, run, and debug as you start to create your scraper. Applications of Electron Considering the flexibility of Electron and all the features it provides, it is poised to be used in a variety of development, testing, and data collection situations. As far as development goes, Electron provides all the features that Chrome does with its DevTools, making it easy to inspect, run arbitrary JavaScript, and put debugger statements. Testing can easily be done on websites that may have issues with bugs in browsers, but work perfectly in a different environment. These tests can easily be hooked up to a continuous integration server too. Data collection, the real reason we are all here, can be done on any type of website, including those with logins, using a familiar API with DevTools for inspection, and optionally run headlessly for automation. What more could one want? How to Scrape with Electron Because of Electron's ability to integrate with Node, there are many different npm modules at your disposal. This takes doing most of the leg work of automating the web scraping process and makes development a breeze. My personal favorite, nightmare, has never let me down. I have used it for tons of different projects from collecting info and automating OAuth processes to grabbing console errors, and also taking screenshots for visual inspection of entire websites and services. Packt's blog actually gives a perfect situation to use a web scraper. On the blog page, you will find a small single-page application that dynamically loads different blog posts using JavaScript. Using Electron, let's collect the latest blog posts so that we can use that information elsewhere. Full disclosure, Packt's Blog server-side renders the first page and could possibly be scraped using traditional methods. This won't be the case for all single-page applications. Prerequisites and Assumptions Following this guide, I assume that you already have Node (version 6+) and npm (version 3+) installed and that you are using some form of a Unix shell. I also assume that you are already inside a directory to do some coding in. Setup First of all, you will need to install some npm modules, so create a package.json like this: { "scripts": { "start": "DEBUG=nightmare babel-node ./main.js" }, "devDependencies": { "babel-cli": "6.18.0", "babel-preset-modern-node": "3.2.0", "babel-preset-stage-0": "6.16.0" }, "dependencies": { "nightmare": "2.8.1" }, "babel": { "presets": [ [ "modern-node", { "version": "6.0" } ], "stage-0" ] } } Using babel we can make use of some of the newer JavaScript utilities like async/await, making our code much more readable. nightmare has electron as a dependency, so there is no need to list that in our package.json (so easy). After this file is made, run npm install as usual. Investgating the Content to be Scraped First, we will need to identify the information we want to collect and how to get it: We go to here and we can see a page of different blog posts, but we are not sure of the order in which they are. We only want the latest and greatest, so let's change the sort order to "Date of Publication (New to Older)". Now we can see that we have only the blog posts that we want. Changing the sort order Next, to make it easier to collect more blog posts, change the number of blog posts shown from 12 to 48. Changing post view Last, but not least, are the blog posts themselves. Packt blog posts Next, we will figure the selectors that we will be using with nightmare to change the page and collect data: Inspecting the sort order selector, we find something like the following HTML: <div class="solr-pager-sort-selector"> <span>Sort By: &nbsp;</span> <select class="solr-page-sort-selector-select selectBox" style="display: none;"> <option value="" selected="">Relevance</option> <option value="ds_blog_release_date asc">Date of Publication (Older - Newer)</option> <option value="ds_blog_release_date desc">Date of Publication (Newer - Older)</option> <option value="sort_title asc">Title (A - Z)</option> <option value="sort_title desc">Title (Z - A)</option> </select> <a class="selectBox solr-page-sort-selector-select selectBox-dropdown" title="" tabindex="0" style="width: 243px; display: inline-block;"> <span class="selectBox-label" style="width: 220.2px;">Relevance</span> <span class="selectBox-arrow">▼</span> </a> </div> Checking out the "View" options, we see the following HTML: <div class="solr-pager-rows-selector"> <span>View: &nbsp;</span> <strong>12</strong> &nbsp; <a class="solr-page-rows-selector-option" data-rows="24">24</a> &nbsp; <a class="solr-page-rows-selector-option" data-rows="48">48</a> &nbsp; </div> Finally, the info we need from the post should look similar to this: <div class="packt-article-line-view float-left"> <div class="packt-article-line-view-image"> <a href="/books/content/mapt-v030-release-notes"> <noscript> &lt;img src="//d1ldz4te4covpm.cloudfront.net/sites/default/files/imagecache/ppv4_article_thumb/Mapt FB PPC3_0.png" alt="" title="" class="bookimage imagecache imagecache-ppv4_article_thumb"/&gt; </noscript> <img src="//d1ldz4te4covpm.cloudfront.net/sites/default/files/imagecache/ppv4_article_thumb/Mapt FB PPC3_0.png" alt="" title="" data-original="//d1ldz4te4covpm.cloudfront.net/sites/default/files/imagecache/ppv4_article_thumb/Mapt FB PPC3_0.png" class="bookimage imagecache imagecache-ppv4_article_thumb" style="opacity: 1;"> <div class="packt-article-line-view-bg"></div> <div class="packt-article-line-view-title">Mapt v.0.3.0 Release Notes</div> </a> </div> <a href="/books/content/mapt-v030-release-notes"> <div class="packt-article-line-view-text ellipsis"> <div> <p>New features and fixes for the Mapt platform</p> </div> </div> </a> </div> Great! Now we have all the information necessary to start collecting data from the page! Creating the Scraper First things first, create a main.js file in the same directory as the package.json. Now let's put some initial code to get the ball rolling on the first step: import Nightmare from 'nightmare'; const URL_BLOG = 'https://www.packtpub.com/books/content/blogs'; const SELECTOR_SORT = '.selectBox.solr-page-sort-selector-select.selectBox-dropdown'; // Viewport must have a width at least 1040 for the desktop version of Packt's blog const nightmare = new Nightmare({ show: true }).viewport(1041, 800); (async() => { await nightmare .goto(URL_BLOG) .wait(SELECTOR_SORT) // Always good to wait before performing an action on an element .click(SELECTOR_SORT); })(); If you try to run this code, you will notice a window pop up with Packt's blog, then resize the window, and then nothing. This is because the sort selector only listens for mousedown events, so we will need to modify our code a little, by changing click to mousedown: await nightmare .goto(BLOG_URL) .wait(SELECTOR_SORT) // Always good to wait before performing an action on an element .mousedown(SELECTOR_SORT); Running the code again, after the mousedown, we get a small HTML dropdown, which we can inspect and see the following: <ul class="selectBox-dropdown-menu selectBox-options solr-page-sort-selector-select-selectBox-dropdown-menu selectBox-options-bottom" style="width: 274px; top: 354.109px; left: 746.188px; display: block;"> <li class="selectBox-selected"><a rel="">Relevance</a></li> <li class=""><a rel="ds_blog_release_date asc">Date of Publication (Older - Newer)</a></li> <li class=""><a rel="ds_blog_release_date desc">Date of Publication (Newer - Older)</a></li> <li class=""><a rel="sort_title asc">Title (A - Z)</a></li> <li class=""><a rel="sort_title desc">Title (Z - A)</a></li> </ul> So, to select the option to sort the blog posts by date, we will need to alter our code a little further (again, it does not work with click, so use mousedown plus mouseup): import Nightmare from 'nightmare'; const URL_BLOG = 'https://www.packtpub.com/books/content/blogs'; const SELECTOR_SORT = '.selectBox.solr-page-sort-selector-select.selectBox-dropdown'; const SELECTOR_SORT_OPTION = '.solr-page-sort-selector-select-selectBox-dropdown-menu > li > a[rel="ds_blog_release_date desc"]'; // Viewport must have a width at least 1040 for the desktop version of Packt's blog const nightmare = new Nightmare({ show: true }).viewport(1041, 800); (async() => { await nightmare .goto(URL_BLOG) .wait(SELECTOR_SORT) // Always good to wait before performing an action on an element .mousedown(SELECTOR_SORT) .wait(SELECTOR_SORT_OPTION) .mousedown(SELECTOR_SORT_OPTION) // Drop down menu doesn't listen for `click` events like normal... .mouseup(SELECTOR_SORT_OPTION); })(); Awesome! We can clearly see the page reload, with posts from newest to oldest. After we have sorted everything, we need to change the number of blog posts shown (finally we can use click; lol!): import Nightmare from 'nightmare'; const URL_BLOG = 'https://www.packtpub.com/books/content/blogs'; const SELECTOR_SORT = '.selectBox.solr-page-sort-selector-select.selectBox-dropdown'; const SELECTOR_SORT_OPTION = '.solr-page-sort-selector-select-selectBox-dropdown-menu > li > a[rel="ds_blog_release_date desc"]'; const SELECTOR_VIEW = '.solr-page-rows-selector-option[data-rows="48"]'; // Viewport must have a width at least 1040 for the desktop version of Packt's blog const nightmare = new Nightmare({ show: true }).viewport(1041, 800); (async() => { await nightmare .goto(URL_BLOG) .wait(SELECTOR_SORT) // Always good to wait before performing an action on an element .mousedown(SELECTOR_SORT) .wait(SELECTOR_SORT_OPTION) .mousedown(SELECTOR_SORT_OPTION) // Drop down menu doesn't listen for `click` events like normal... .mouseup(SELECTOR_SORT_OPTION) .wait(SELECTOR_VIEW) .click(SELECTOR_VIEW); })(); Collecting the data is next; all we need to do is evaluate parts of the HTML and return the formatted information. The way the evaluate function works is by stringifying the function provided to it and injecting it into Electron's event loop. Because the function gets stringified, only a function that does not rely on outside variables or functions will execute properly. The value that is returned by this function must also be able to be stringified, so only JSON, strings, numbers, and booleans are applicable. import Nightmare from 'nightmare'; const URL_BLOG = 'https://www.packtpub.com/books/content/blogs'; const SELECTOR_SORT = '.selectBox.solr-page-sort-selector-select.selectBox-dropdown'; const SELECTOR_SORT_OPTION = '.solr-page-sort-selector-select-selectBox-dropdown-menu > li > a[rel="ds_blog_release_date desc"]'; const SELECTOR_VIEW = '.solr-page-rows-selector-option[data-rows="48"]'; // Viewport must have a width at least 1040 for the desktop version of Packt's blog const nightmare = new Nightmare({ show: true }).viewport(1041, 800); (async() => { await nightmare .goto(URL_BLOG) .wait(SELECTOR_SORT) // Always good to wait before performing an action on an element .mousedown(SELECTOR_SORT) .wait(SELECTOR_SORT_OPTION) .mousedown(SELECTOR_SORT_OPTION) // Drop down menu doesn't listen for `click` events like normal... .mouseup(SELECTOR_SORT_OPTION) .wait(SELECTOR_VIEW) .click(SELECTOR_VIEW) .evaluate( () => { let posts = []; document.querySelectorAll('.packt-article-line-view').forEach( post => { posts = posts.concat({ image: post.querySelector('img').src, title: post.querySelector('.packt-article-line-view-title').textContent.trim(), link: post.querySelector('a').href, description: post.querySelector('p').textContent.trim(), }); } ); return posts; } ) .end() .then( result => console.log(result) ); })(); Once you run your function again, you should get a very long array of objects containing information about each post. There you have it! You have successfully scraped a page using Electron! There’s a bunch more of possibilities and tricks with this, but hopefully this small example gives you a good idea of what can be done. About the author Dylan Frankland is a frontend engineer at Narvar. He is an agile web developer, with over 4 years of experience developing and designing for start-ups and medium-sized businesses to create a functional, fast, and beautiful web experiences.
Read more
  • 0
  • 0
  • 31612

article-image-4-key-findings-from-the-state-of-javascript-2018-developer-survey
Prasad Ramesh
20 Nov 2018
4 min read
Save for later

4 key findings from The State of JavaScript 2018 developer survey

Prasad Ramesh
20 Nov 2018
4 min read
Three JavaScript developers surveyed over 20,000 JavaScript developers to find out what’s happening within the language and its huge ecosystem. From usage to satisfaction to learning habits, this State if JavaScript 2018 report offered another valuable insight on a community that is still going strong, despite the landscape continuing to change. You can check out the results of the State of JavaScript 2018 survey in detail here but keep reading to find out 4 things we found interesting about the State of JavaScript 2018 survey. JavaScript developers love ES6 and TypeScript ES6 and TypeScript were the most well received. 86.3% and 46.7% developers respectively have used and would use these languages again. ClojureScript, Elm, and Flow, however, don’t seem to pique many developers' interests these days (unsurprisingly). React rules the front-end frameworks - Angular's popularity may be dwindling There has been a big battle between a couple of frameworks in the front-end side of web development - namely between React, Vue, and Angular. The State of JavaScript 2018 survey suggests that React is winning out, with Vue in second position. 64.8% and 28.8% developers said that they would use React and Vue.js respectively, again. However, Vue is growing in popularity - 46.6% of respondents expressed an interest in learning it. However, news wasn't great for Angular - 33.8% of respondents said that they wouldn't use Angular again. Vue is gaining popularity as. Ember and polymer were less than well received as more than 50% of the responses for both indicated no interest in learning them. Preact and Polymer, meanwhile, are perhaps still a little new on the scene: 28.1% and 18.5% respondents had never even heard of these frameworks. Vue.js 3.0 is ditching JavaScript for TypeScript. Learn more here. Redux is the most used in the data layer - but JavaScript developers want to learn GraphQL Redux is the most used in the data layer - but JavaScript developers want to learn GraphQL When it comes to data, Redux is the most popular library with 47.2% developers saying that they would use it again. GraphQL is second with 20.4% of respondents vouching for it. But Redux shouldn’t be complacent - 62.5% developers also want to learn GraphQL. It looks like the Redux and GraphQL debate is going to continue well into 2019. What the consensus will be in 12 months time is anyone’s guess. Why do React developers love Redux? Find out here. Express.js popularity confirms Node.js as JavaScript’s quiet hero It was observed that there haven’t been any major break breakthroughs in this area in recent years. But that is, perhaps, a good thing when you consider the frantic pace of change in other areas of JavaScript. It probably also has a lot to do with the dominance of Node.js in this area. Express, a Node.js framework, is by far the most popular, with 64.7% of developers taking the survey saying they would use it again. Sadly, it appears Meteor is languishing despite its meteoric hype just a few years ago. 49.4% of developers had heard of it, but said they had no interest in learning it. In conclusion: The landscape is becoming more clearly defined, but the JavaScript developer role is changing A few years ago, the JavaScript ecosystem was chaotic and almost incoherent. Every week seemed to bring a new framework demanding your attention. It looks, as we move towards the end of the decade, that things are a lot different now - React has established itself at the forefront of the front end, while TypeScript appears to have embedded itself within the ecosystem too. With GraphQL also generating interest, and competing with Redux, we're seeing a clear shift in what JavaScript developers are doing, and what they're being asked to do. As the stack expands, managing data sources and building for speed and scalability is now a problem right at the heart of JavaScript development, not just on its fringes.
Read more
  • 0
  • 0
  • 31575
article-image-javascript-async-programming-using-promises-tutorial
Pavan Ramchandani
23 Jul 2018
10 min read
Save for later

JavaScript async programming using Promises [Tutorial]

Pavan Ramchandani
23 Jul 2018
10 min read
JavaScript now has a new native pattern for writing asynchronous code called the Promise pattern. This new pattern removes the common code issues that the event and callback pattern had. It also makes the code look more like synchronous code. A promise (or a Promise object) represents an asynchronous operation. Existing asynchronous JavaScript APIs are usually wrapped with promises, and the new JavaScript APIs are purely implemented using promises. Promises are new in JavaScript but are already present in many other programming languages. Programming languages, such as C# 5, C++ 11, Swift, Scala, and more are some examples that support promises. In this tutorial, we will see how to use promises in JavaScript. This article is an excerpt from the book, Learn ECMAScript - Second Edition, written by Mehul Mohan and Narayan Prusty. Promise states A promise is always in one of these states: Fulfilled: If the resolve callback is invoked with a non-promise object as the argument or no argument, then we say that the promise is fulfilled Rejected: If the rejecting callback is invoked or an exception occurs in the executor scope, then we say that the promise is rejected Pending: If the resolve or reject callback is yet to be invoked, then we say that the promise is pending Settled: A promise is said to be settled if it's either fulfilled or rejected, but not pending Once a promise is fulfilled or rejected, it cannot be transitioned back. An attempt to transition it will have no effect. Promises versus callbacks Suppose you wanted to perform three AJAX requests one after another. Here's a dummy implementation of that in callback-style: ajaxCall('http://example.com/page1', response1 => { ajaxCall('http://example.com/page2'+response1, response2 => { ajaxCall('http://example.com/page3'+response2, response3 => { console.log(response3) } }) }) You can see how quickly you can enter into something known as callback-hell. Multiple nesting makes code not only unreadable but also difficult to maintain. Furthermore, if you start processing data after every call, and the next call is based on a previous call's response data, the complexity of the code will be unmatchable. Callback-hell refers to multiple asynchronous functions nested inside each other's callback functions. This makes code harder to read and maintain. Promises can be used to flatten this code. Let's take a look: ajaxCallPromise('http://example.com/page1') .then( response1 => ajaxCallPromise('http://example.com/page2'+response1) ) .then( response2 => ajaxCallPromise('http://example.com/page3'+response2) ) .then( response3 => console.log(response3) ) You can see the code complexity is suddenly reduced and the code looks much cleaner and readable. Let's first see how ajaxCallPromise would've been implemented. Please read the following explanation for more clarity of preceding code snippet. Promise constructor and (resolve, reject) methods To convert an existing callback type function to Promise, we have to use the Promise constructor. In the preceding example, ajaxCallPromise returns a Promise, which can be either resolved or rejected by the developer. Let's see how to implement ajaxCallPromise: const ajaxCallPromise = url => { return new Promise((resolve, reject) => { // DO YOUR ASYNC STUFF HERE $.ajaxAsyncWithNativeAPI(url, function(data) { if(data.resCode === 200) { resolve(data.message) } else { reject(data.error) } }) }) } Hang on! What just happened there? First, we returned Promise from the ajaxCallPromise function. That means whatever we do now will be a Promise. A Promise accepts a function argument, with the function itself accepting two very special arguments, that is, resolve and reject. resolve and reject are themselves functions. When, inside a Promise constructor function body, you call resolve or reject, the promise acquires a resolved or rejected value that is unchangeable later on. We then make use of the native callback-based API and check if everything is OK. If everything is indeed OK, we resolve the Promise with the value being the message sent by the server (assuming a JSON response). If there was an error in the response, we reject the promise instead. You can return a promise in a then call. When you do that, you can flatten the code instead of chaining promises again.For example, if foo() and bar() both return Promise, then, instead of: foo().then( res => { bar().then( res2 => { console.log('Both done') }) }) We can write it as follows: foo() .then( res => bar() ) // bar() returns a Promise .then( res => { console.log('Both done') }) This flattens the code. The then (onFulfilled, onRejected) method The then() method of a Promise object lets us do a task after a Promise has been fulfilled or rejected. The task can also be another event-driven or callback-based asynchronous operation. The then() method of a Promise object takes two arguments, that is, the onFulfilled and onRejected callbacks. The onFulfilled callback is executed if the Promise object was fulfilled, and the onRejected callback is executed if the Promise was rejected. The onRejected callback is also executed if an exception is thrown in the scope of the executor. Therefore, it behaves like an exception handler, that is, it catches the exceptions. The onFulfilled callback takes a parameter, that is, the fulfilment value of the promise. Similarly, the onRejected callback takes a parameter, that is, the reason for rejection: ajaxCallPromise('http://example.com/page1').then( successData => { console.log('Request was successful') }, failData => { console.log('Request failed' + failData) } ) When we reject the promise inside the ajaxCallPromise definition, the second function will execute (failData one) instead of the first function. Let's take one more example by converting setTimeout() from a callback to a promise. This is how setTimeout() looks: setTimeout( () => { // code here executes after TIME_DURATION milliseconds }, TIME_DURATION) A promised version will look something like the following: const PsetTimeout = duration => { return new Promise((resolve, reject) => { setTimeout( () => { resolve() }, duration); }) } // usage: PsetTimeout(1000) .then(() => { console.log('Executes after a second') }) Here we resolved the promise without a value. If you do that, it gets resolved with a value equal to undefined. The catch (onRejected) method The catch() method of a Promise object is used instead of the then() method when we use the then() method only to handle errors and exceptions. There is nothing special about how the catch() method works. It's just that it makes the code much easier to read, as the word catch makes it more meaningful. The catch() method just takes one argument, that is, the onRejected callback. The onRejected callback of the catch() method is invoked in the same way as the onRejected callback of the then() method. The catch() method always returns a promise. Here is how a new Promise object is returned by the catch() method: If there is no return statement in the onRejected callback, then a new fulfilled Promise is created internally and returned. If we return a custom Promise, then it internally creates and returns a new Promise object. The new promise object resolves the custom promise object. If we return something else other than a custom Promise in the onRejected callback, then a new Promise object is created internally and returned. The new Promise object resolves the returned value. If we pass null instead of the onRejected callback or omit it, then a callback is created internally and used instead. The internally created onRejected callback returns a rejected Promise object. The reason for the rejection of the new Promise object is the same as the reason for the rejection of a parent Promise object. If the Promise object to which catch() is called gets fulfilled, then the catch() method simply returns a new fulfilled promise object and ignores the onRejected callback. The fulfillment value of the new Promise object is the same as the fulfillment value of the parent Promise. To understand the catch() method, consider this code: ajaxPromiseCall('http://invalidURL.com') .then(success => { console.log(success) }, failed => { console.log(failed) }); This code can be rewritten in this way using the catch() method: ajaxPromiseCall('http://invalidURL.com') .then(success => console.log(success)) .catch(failed => console.log(failed)); These two code snippets work more or less in the same way. The Promise.resolve(value) method The resolve() method of the Promise object takes a value and returns a Promise object that resolves the passed value. The resolve() method is basically used to convert a value to a Promise object. It is useful when you find yourself with a value that may or may not be a Promise, but you want to use it as a Promise. For example, jQuery promises have different interfaces from ES6 promises. Therefore, you can use the resolve() method to convert jQuery promises into ES6 promises. Here is an example that demonstrates how to use the resolve() method: const p1 = Promise.resolve(4); p1.then(function(value){ console.log(value); }); //passed a promise object Promise.resolve(p1).then(function(value){ console.log(value); }); Promise.resolve({name: "Eden"}) .then(function(value){ console.log(value.name); }); The output is as follows: 4 4 Eden The Promise.reject(value) method The reject() method of the Promise object takes a value and returns a rejected Promise object with the passed value as the reason. Unlike the Promise.resolve() method, the reject() method is used for debugging purposes and not for converting values into promises. Here is an example that demonstrates how to use the reject() method: const p1 = Promise.reject(4); p1.then(null, function(value){ console.log(value); }); Promise.reject({name: "Eden"}) .then(null, function(value){ console.log(value.name); }); The output is as follows: 4 Eden The Promise.all(iterable) method The all() method of the Promise object takes an iterable object as an argument and returns a Promise that fulfills when all of the promises in the iterable object have been fulfilled. This can be useful when we want to execute a task after some asynchronous operations have finished. Here is a code example that demonstrates how to use the Promise.all() method: const p1 = new Promise(function(resolve, reject){ setTimeout(function(){ resolve(); }, 1000); }); const p2 = new Promise(function(resolve, reject){ setTimeout(function(){ resolve(); }, 2000); }); const arr = [p1, p2]; Promise.all(arr).then(function(){ console.log("Done"); //"Done" is logged after 2 seconds }); If the iterable object contains a value that is not a Promise object, then it's converted to the Promise object using the Promise.resolve() method. If any of the passed promises get rejected, then the Promise.all() method immediately returns a new rejected Promise for the same reason as the rejected passed Promise. Here is an example to demonstrate this: const p1 = new Promise(function(resolve, reject){ setTimeout(function(){ reject("Error"); }, 1000); }); const p2 = new Promise(function(resolve, reject){ setTimeout(function(){ resolve(); }, 2000); }); const arr = [p1, p2]; Promise.all(arr).then(null, function(reason){ console.log(reason); //"Error" is logged after 1 second }); The Promise.race(iterable) method The race() method of the Promise object takes an iterable object as the argument and returns a Promise that fulfills or rejects as soon as one of the promises in the iterable object is fulfilled or rejected, with the fulfillment value or reason from that Promise. As the name suggests, the race() method is used to race between promises and see which one finishes first. Here is a code example that shows how to use the race() method: var p1 = new Promise(function(resolve, reject){ setTimeout(function(){ resolve("Fulfillment Value 1"); }, 1000); }); var p2 = new Promise(function(resolve, reject){ setTimeout(function(){ resolve("fulfillment Value 2"); }, 2000); }); var arr = [p1, p2]; Promise.race(arr).then(function(value){ console.log(value); //Output "Fulfillment value 1" }, function(reason){ console.log(reason); }); Now at this point, I assume you have a basic understanding of how promises work, what they are, and how to convert a callback-like API into a promised API. Let's take a look at async/await, the future of asynchronous programming. If you found this article useful, do check out the book Learn ECMAScript, Second Edition for learning the ECMAScript standards to design your web applications. Implementing 5 Common Design Patterns in JavaScript (ES8) What's new in ECMAScript 2018 (ES9)? How to build a weather app using Kotlin for JavaScript
Read more
  • 0
  • 0
  • 30970

article-image-create-enterprise-grade-angular-forms-typescript-tutorial
Sugandha Lahoti
04 Jul 2018
11 min read
Save for later

Create enterprise-grade Angular forms in TypeScript [Tutorial]

Sugandha Lahoti
04 Jul 2018
11 min read
Typescript is an open-source programming language which adds optional static typing to Javascript. To give you a flavor of the benefits of TypeScript, let’s have a very quick look at some of the things that TypeScript brings to the table: A compilation step Strong or static typing Type definitions for popular JavaScript libraries Encapsulation Private and public member variable decorators In this article, we will learn how to build forms with typescript. We will cover as much as it takes to build business applications that collect user information. Here is a breakdown of what you should expect from this article: Typed form input and output Form controls Validation Form submission and handling This article is an excerpt from the book, TypeScript 2.x for Angular Developers, written by Chris Nwamba. Creating types for forms We want to try to utilize TypeScript as much as possible, as it simplifies our development process and makes our app behavior more predictable. For this reason, we will create a simple data class to serve as a type for the form values. First, create a new Angular project to follow along with the examples. Then, use the following command to create a new class: ng g class flight The class is generated in the app folder; replace its content with the following data class: export class Flight { constructor( public fullName: string, public from: string, public to: string, public type: string, public adults: number, public departure: Date, public children?: number, public infants?: number, public arrival?: Date, ) {} } This class represents all the values our form (yet to be created) will have. The properties that are succeeded by a question mark (?) are optional, which means that TypeScript will throw no errors when the respective values are not supplied. Before jumping into creating forms, let's start with a clean slate. Replace the app.component.html file with the following: <div class="container"> <h3 class="text-center">Book a Flight</h3> <div class="col-md-offset-3 col-md-6"> <!-- TODO: Form here --> </div> </div> Run the app and leave it running. You should see the following at port 4200 of localhost (remember to include Bootstrap): The form module Now that we have a contract that we want the form to follow, let's now generate the form's component: ng g component flight-form The command also adds the component as a declaration to our App module: import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppComponent } from './app.component'; import { FlightFormComponent } from './flight-form/flight-form.component'; @NgModule({ declarations: [ AppComponent, // Component added after // being generated FlightFormComponent ], imports: [ BrowserModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { } What makes Angular forms special and easy to use are functionalities provided out-of-the-box, such as the NgForm directive. Such functionalities are not available in the core browser module but in the form module. Hence, we need to import them: import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; // Import the form module import { FormsModule } from '@angular/forms'; import { AppComponent } from './app.component'; import { FlightFormComponent } from './flight-form/flight-form.component'; @NgModule({ declarations: [ AppComponent, FlightFormComponent ], imports: [ BrowserModule, // Add the form module // to imports array FormsModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { } Simply importing and adding FormModule to the imports array is all we needed to do. Two-way binding The perfect time to start showing some form controls using the form component in the browser is right now. Keeping the state in sync between the data layer (model) and the view can be very challenging, but with Angular it's just a matter of using one directive exposed from FormModule: <!-- ./app/flight-form/flight-form.component.html --> <form> <div class="form-group"> <label for="fullName">Full Name</label> <input type="text" class="form-control" [(ngModel)]="flightModel.fullName" name="fullName" > </div> </form> Angular relies on the name attribute internally to carry out binding. For this reason, the name attribute is required. Pay attention to [(ngModel)]="flightModel.fullName"; it's trying to bind a property on the component class to the form. This model will be of the Flight type, which is the class we created earlier: // ./app/flight-form/flight-form.component.ts import { Component, OnInit } from '@angular/core'; import { Flight } from '../flight'; @Component({ selector: 'app-flight-form', templateUrl: './flight-form.component.html', styleUrls: ['./flight-form.component.css'] }) export class FlightFormComponent implements OnInit { flightModel: Flight; constructor() { this.flightModel = new Flight('', '', '', '', 0, '', 0, 0, ''); } ngOnInit() {} } The flightModel property is added to the component as a Flight type and initialized with some default values. Include the component in the app HTML, so it can be displayed in the browser: <div class="container"> <h3 class="text-center">Book a Flight</h3> <div class="col-md-offset-3 col-md-6"> <app-flight-form></app-flight-form> </div> </div> This is what you should have in the browser: To see two-way binding in action, use interpolation to display the value of flightModel.fullName. Then, enter a value and see the live update: <form> <div class="form-group"> <label for="fullName">Full Name</label> <input type="text" class="form-control" [(ngModel)]="flightModel.fullName" name="fullName" > {{flightModel.fullName}} </div> </form> Here is what it looks like: More form fields Let's get hands-on and add the remaining form fields. After all, we can't book a flight by just supplying our names. The from and to fields are going to be select boxes with a list of cities we can fly into and out of. This list of cities will be stored right in our component class, and then we can iterate over it in the template and render it as a select box: export class FlightFormComponent implements OnInit { flightModel: Flight; // Array of cities cities:Array<string> = [ 'Lagos', 'Mumbai', 'New York', 'London', 'Nairobi' ]; constructor() { this.flightModel = new Flight('', '', '', '', 0, '', 0, 0, ''); } } The array stores a few cities from around the world as strings. Let's now use the ngFor directive to iterate over the cities and display them on the form using a select box: <div class="row"> <div class="col-md-6"> <label for="from">From</label> <select type="text" id="from" class="form-control" [(ngModel)]="flightModel.from" name="from"> <option *ngFor="let city of cities" value="{{city}}">{{city}}</option> </select> </div> <div class="col-md-6"> <label for="to">To</label> <select type="text" id="to" class="form-control" [(ngModel)]="flightModel.to" name="to"> <option *ngFor="let city of cities" value="{{city}}">{{city}}</option> </select> </div> </div> Neat and clean! You can open the browser and see it right there: The select drop-down, when clicked, shows a list of cities, as expected: Next, let's add the trip type field (radio buttons), the departure date field (date control), and the arrival date field (date control): <div class="row" style="margin-top: 15px"> <div class="col-md-5"> <label for="" style="display: block">Trip Type</label> <label class="radio-inline"> <input type="radio" name="type" [(ngModel)]="flightModel.type" value="One Way"> One way </label> <label class="radio-inline"> <input type="radio" name="type" [(ngModel)]="flightModel.type" value="Return"> Return </label> </div> <div class="col-md-4"> <label for="departure">Departure</label> <input type="date" id="departure" class="form-control" [(ngModel)]="flightModel.departure" name="departure"> </div> <div class="col-md-3"> <label for="arrival">Arrival</label> <input type="date" id="arrival" class="form-control" [(ngModel)]="flightModel.arrival" name="arrival"> </div> </div> How the data is bound to the controls is very similar to the text and select fields that we created previously. The major difference is the types of control (radio buttons and dates): Lastly, add the number of passengers (adults, children, and infants): <div class="row" style="margin-top: 15px"> <div class="col-md-4"> <label for="adults">Adults</label> <input type="number" id="adults" class="form-control" [(ngModel)]="flightModel.adults" name="adults"> </div> <div class="col-md-4"> <label for="children">Children</label> <input type="number" id="children" class="form-control" [(ngModel)]="flightModel.children" name="children"> </div> <div class="col-md-4"> <label for="infants">Infants</label> <input type="number" id="infants" class="form-control" [(ngModel)]="flightModel.infants" name="infants"> </div> </div> The passengers section are all of the number type because we are just expected to pick the number of passengers coming onboard from each category: Validating the form and form fields Angular greatly simplifies form validation by using its built-in directives and state properties. You can use the state property to check whether a form field has been touched. If it's touched but violates a validation rule, you can use the ngIf directive to display associated errors. Let's see an example of validating the full name field: <div class="form-group"> <label for="fullName">Full Name</label> <input type="text" id="fullName" class="form-control" [(ngModel)]="flightModel.fullName" name="fullName" #name="ngModel" required minlength="6"> </div> We just added three extra significant attributes to our form's full name field: #name, required, and minlength. The #name attribute is completely different from the name attribute in that the former is a template variable that holds information about this given field via the ngModel value while the latter is the usual form input name attribute. In Angular, validation rules are passed as attributes, which is why required and minlength are there. Yes, the fields are validated, but there are no feedbacks to the user on what must have gone wrong. Let's add some error messages to be shown when form fields are violated: <div *ngIf="name.invalid && (name.dirty || name.touched)" class="text-danger"> <div *ngIf="name.errors.required"> Name is required. </div> <div *ngIf="name.errors.minlength"> Name must be at least 6 characters long. </div> </div> The ngIf directive shows these div elements conditionally: If the form field has been touched but there's no value in it, the Name is required error is shown Name must be at least 6 characters long is also shown when the field is touched but the content length is less than 6. The following two screenshots show these error outputs in the browser: A different error is shown when a value is entered but the value text count is not up to 6: Submitting forms We need to consider a few factors before submitting a form: Is the form valid? Is there a handler for the form prior to submission? To make sure that the form is valid, we can disable the Submit button: <form #flightForm="ngForm"> <div class="form-group" style="margin-top: 15px"> <button class="btn btn-primary btn-block" [disabled]="!flightForm.form.valid"> Submit </button> </div> </form> First, we add a template variable called flightForm to the form and then use the variable to check whether the form is valid. If the form is invalid, we disable the button from being clicked: To handle the submission, add an ngSubmit event to the form. This event will be called when the button is clicked: <form #flightForm="ngForm" (ngSubmit)="handleSubmit()"> ... </form> You can now add a class method, handleSubmit, to handle the form submission. A simple log to the console may be just enough for this example: export class FlightFormComponent implements OnInit { flightModel: Flight; cities:Array<string> = [ ... ]; constructor() { this.flightModel = new Flight('', '', '', '', 0, '', 0, 0, ''); } // Handle for submission handleSubmit() { console.log(this.flightModel); } } We discussed about collecting user inputs via forms. We covered important features of forms, such as typed inputs, validation, two-way binding, submission, and so on. All these interesting methods will prepare you for getting started with building business applications. If you liked our article, you may read our book TypeScript 2.x for Angular Developers, to learn to use typed DOM events and event handling among other interesting things to do with Typescript. Typescript 2.9 release candidate is here How to install and configure TypeScript How to work with classes in Typescript
Read more
  • 0
  • 0
  • 30546

article-image-firefox-70-released-with-better-security-css-and-javascript-improvements
Savia Lobo
23 Oct 2019
6 min read
Save for later

Firefox 70 released with better security, CSS, and JavaScript improvements

Savia Lobo
23 Oct 2019
6 min read
Mozilla team announced the much-awaited release of Firefox 70 yesterday with amazing new features like secure password generation with Lockwise and the new Firefox Privacy Protection Report. Firefox 70 also includes a plethora of additions for developers such as DOM mutation breakpoints and inactive CSS rule indicators in the DevTools, several new CSS text properties, two-value display syntax, and JS numeric separators, and much more. Firefox 70 centers around enhanced privacy and security The new Firefox 70 includes an Enhanced Tracking Protection, which includes a Firefox Privacy Protection Report that gives additional details and more visibility into how you’re being tracked online so you can better combat it. The Enhanced Tracking Protection was set up as default by the browser in September this year. The report highlights how ETP prevents third-party trackers from building a user’s profile based on their online activity. The report also includes the number of cross-site and social media trackers, finger-printers and crypto-miners Mozilla blocked. The report also helps users to keep themselves updated with Firefox Monitor and Firefox Lockwise. Firefox Monitor helps users to get a summary of the number of unsafe passwords that may have been used in a breach so that you can take action to update and change those passwords. Firefox Lockwise helps users to manage passwords and different synced devices. Firefox Lockwise includes a button where users can click to view their logins and updates. They can also have the ability to quickly view and manage how many devices they syncing and sharing passwords with. To know more about security in Firefox 70, read Mozilla’s blog. What’s new in Firefox 70 Updated HTML forms and secure passwords To generate secure passwords, the team has updated HTML input elements. Here, any input element of type password will have an option to generate a secure password available in the context menu, which can then be stored in Lockwise. In addition, any type="password" field with autocomplete=”new-password” set on it will have an autocomplete UI to generate a new password in-context. New CSS improvements Firefox 70 includes some CSS improvements like new options for styling underlines and new set of two-keyword values. Options for styling underlines include three new properties for text-decoration (underline): text-decoration-thickness: sets the thickness of lines added via text-decoration. text-underline-offset: sets the distance between a text-decoration and the text it is set on. Bear in mind that this only works on underlines. text-decoration-skip-ink: sets whether underlines and overlines are drawn if they cross descenders and ascenders. The default value, auto, causes them to only be drawn where they do not cross over a glyph. To allow underlines to cross glyphs, set the value to none. Two-keyword display values Until now, the display property has taken a single value. However, the team says that “the boxes on a page have an outer display type, which determines how the box is laid out in relation to other boxes on the page, and an inner display type, which determines how the box’s children will behave.” The two-keyword values allow you to explicitly specify the outer and inner display values. In supporting browsers (which currently includes only Firefox), the single keyword values will map to new two-keyword values, for example: display: flex; is equivalent to display: block flex; display: inline-flex; is equivalent to display: inline flex; JavaScript improvements Firefox 70 now supports numeric separators for JavaScript. Underscores can now be used as separators in large numbers so that they are more readable. Other improvements in JavaScript include: Intl improvements Firefox 70 includes improved JavaScript i18n (internationalization), starting with the implementation of the Intl.RelativeTimeFormat.formatToParts() method. This is a special version of Intl.RelativeTimeFormat.format() that returns an array of objects, each one representing a part of the value, rather than returning a string of the localized time value. Also,  Intl.NumberFormat.format() and Intl.NumberFormat.formatToParts() now accept BigInt values. Performance Improvements The inclusion of the new baseline interpreter has speeded up JavaScript. The code for the new interpreter includes shared code from the existing Baseline JIT. You can read more about the interpreter on The Baseline Interpreter: a faster JS interpreter in Firefox 70. New Developer tools The Developer Tools Accessibility panel now includes an audit for keyboard accessibility and a color deficiency simulator for systems with WebRender enabled. Pause option in DOM Mutation in Debugger DOM Mutation Breakpoints (aka DOM Change Breakpoints) let you pause scripts that add, remove, or change specific elements. Once a DOM mutation breakpoint is set, you’ll see it listed under “DOM Mutation Breakpoints” in the right-hand pane of the Debugger; this is also where you’ll see breaks reported. Source: Mozilla Hacks Color contrast information in the color picker! In the CSS Rules view, you can click foreground colors with the color picker to determine if their contrast with the background color meets accessibility guidelines. Accessibility inspector: keyboard checks The Accessibility inspector‘s Check for issues dropdown now includes keyboard accessibility checks: Selecting this option causes Firefox to go through each node in the accessibility tree and highlight all that have a keyboard accessibility issue: Hovering over or clicking each one will reveal information about what the issue is, along with a “Learn more” link for more details on how to fix it. Web socket inspector In Firefox DevEdition, the Network monitor now has a new “Messages” panel, which appears when you are monitoring a web socket connection (i.e. a 101 response). This can be used to inspect web socket frames sent and received through the connection. This functionality was originally supposed to be in Firefox 70 general release, but the team had a few more bugs to resolve, so expect it in Firefox 71! For now, users can explore it in the DevEdition. Fixed issues in Firefox 70 Built-in Firefox pages now follow the system dark mode preference Aliased theme properties have been removed, which may affect some themes Passwords can now be imported from Chrome on macOS in addition to existing support for Windows Readability is now greatly improved on under- or overlined texts, including links. The lines will now be interrupted instead of crossing over a glyph. Improved privacy and security indicators A new crossed-out lock icon will indicate sites delivered via insecure HTTP The formerly green lock icon is now grey The Extended Validation (EV) indicator has been moved to the identity popup that appears when clicking the lock icon To know more about other improvements and bug fixes in Firefox 70 in detail read Mozilla’s official blog. Google and Mozilla to remove Extended Validation indicators in Chrome 77 and Firefox 70 Firefox 69 allows default blocking of third-party tracking cookies and cryptomining for all users Mozilla Thunderbird 78 will include OpenPGP support, expected to be released by Summer 2020
Read more
  • 0
  • 0
  • 29223
article-image-build-progressive-web-apps-firebase
Savia Lobo
24 May 2018
19 min read
Save for later

Build powerful progressive web apps with Firebase

Savia Lobo
24 May 2018
19 min read
Progressive Web Apps describe a collection of technologies, design concepts, and Web APIs. They work in tandem to provide an app-like experience on the mobile web. In this tutorial, we'll discuss diverse recipes and show what it takes to turn any application into a powerful, fully-optimized progressive web application using Firebase magic. This article is an excerpt taken from the book,' Firebase Cookbook', written by Houssem Yahiaoui. In this book, you will learn how to create cross-platform mobile apps, integrate Firebase in native platforms, and learn how to monetize your mobile applications using Admob for Android and iOS. Integrating Node-FCM in NodeJS server We'll see how we can fully integrate the FCM (Firebase Cloud Messaging) with any Nodejs application. This process is relatively easy and straightforward, and we will see how it can be done in a matter of minutes. How to do it... Let's ensure that our working environment is ready for our project, so let's install a couple of dependencies in order to ensure that everything will run smoothly: Open your terminal--in case you are using macOS/Linux--or your cmd--if you're using Windows--and write down the following command: ~> npm install fcm-push --save By using this command, we are downloading and installing the fcm-push library locally. If this is executed, it will help with managing the process of sending web push notification to our users. The NodeJS ecosystem has npm as part of it. So in order to have it on your working machine, you will have to download NodeJS and configure your system within. Here's the official NodeJS link; download and install the suitable version to your system: https://nodejs.org/en/download/. Now that we have successfully installed the library locally, in order to integrate it with our applications and start using it, we will just need another line of code. Within your local development project, create a new file that will host the functionality and simply implement the following code: const FCM = require('fcm-push'); Congratulations! We're typically done. In subsequent recipes, we'll see how to manage our way through the sending process and how we can successfully send our user's web push notification. Implementing service workers Service workers were, in fact, the missing piece in the web scenes of the past. They are what give us the feel of reactivity to any state that a web application, after integrating, can have from, for example, a notification message, an offline-state (no internet connection) and more. In this recipe, we'll see how we can integrate service worker into our application. Service workers files are event-driven, so everything that will happen inside them will be event based. Since it's JavaScript, we can always hook up listeners to any event. To do that, we will want to give a special logic knowing that if you will use this logic, the event will behave in its default way. You can read more about service workers and know how you can incorporate them--to achieve numerous awesome features to your application that our book won't cover--from https://developers.google.com/web/fundamentals/getting-started/primers/service-workers. How to do it... Services workers will live in the browser, so including them within your frontend bundle is the most suitable place for them. Keeping that in mind, let's create a file called firebase-messaging-sw.js and manifest.json file. The JavaScript file will be our service worker file and will host all major workload, and the JSON file will simply be a metadata config file. After that, ensure that you also create app.js file, where this file will be the starting point for our Authorization and custom UX.  We will look into the importance of each file individually later on, but for now, go back to the firebase-messaging-sw.js file and write the following: //[*] Importing Firebase Needed Dependencies importScripts('https://www.gstatic.com/firebasejs/ 3.5.2/firebase-app.js'); importScripts('https://www.gstatic.com/firebasejs/ 3.5.2/firebase-messaging.js'); // [*] Firebase Configurations var config = { apiKey: "", authDomain: "", databaseURL: "", storageBucket: "", messagingSenderId: "" }; //[*] Initializing our Firebase Application. firebase.initializeApp(config); // [*] Initializing the Firebase Messaging Object. const messaging = firebase.messaging(); // [*] SW Install State Event. self.addEventListener('install', function(event) { console.log("Install Step, let's cache some files =D"); }); // [*] SW Activate State Event. self.addEventListener('activate', function(event) { console.log('Activated!', event);}); Within any service worker file, the install event is always fired first. Within this event, we can handle and add custom logic to any event we want. This can range from saving a local copy of our application in the browser cache to practically anything we want. Inside your metadata file, which will be the manifest.json files, write the following line: { "name": "Firebase Cookbook", "gcm_sender_id": "103953800507" } How it works... For this to work, we're doing the following: Importing using importScripts while considering this as the script tag with the src attribute in HTML, the firebase app, and the messaging libraries. Then, we're introducing our Firebase config object; we've already discussed where you can grab that object content in the past chapters. Initializing our Firebase app with our config file. Creating a new reference from the firebase.messaging library--always remember that everything in Firebase starts with a reference. We're listening to the install and activate events and printing some stdout friendly message to the browser debugger. Also, within our manifest.json file, we're adding the following metadata: The application name (optional). The gcm_sender_id with the given value. Keep in mind that this value will not change for any new project you have or will create in the future. The gcm_sender_id added line might get deprecated in the future, so keep an eye on that. Implementing sending/receiving registration using Socket.IO By now, we've integrated our FCM server and made our service worker ready to host our awesome custom logic. Like we mentioned, we're about to send web push notifications to our users to expand and enlarge their experience without application. Lately, web push notification is being considered as an engagement feature that any cool application nowadays, ranging from Facebook and Twitter to numerous e-commerce sites, is making good use of. So in the first approach, let's see how we can make it happen with Socket.IO. In order to make the FCM server aware of any client--basically, a browser--Browser OEM has what we call a registration_id. This token is a unique token for every browser that will represent our clients by their browsers and needs to be sent to the FCM server. Each browser generates its own registration_id token. So if your user uses, for instance, chrome for their first interaction with the server and they used firefox for their second experience, the web push notification message won't be sent, and they need to send another token so that they can be notified. How to do it... Now, go back to your NodeJS project that was created in the first recipe. Let's download the node.js socket.io dependency: ~> npm install express socket.io --save Socket.io is also event-based and lets us create our custom event for everything we have, plus some native one for connections. Also, we've installed ExpressJS for configuration sake in order to create a socket.io server. Now after doing that, we need to configure our socket.io server using express. In this case, do as shown in the following code: const express = require('express'); const app = express(); app.io = require('socket.io')(); // [*] Configuring our static files. app.use(express.static('public/')); // [*] Configuring Routes. app.get('/', (req, res) => { res.sendFile(__dirname + '/public/index.html'); }); // [*] Configuring our Socket Connection. app.io.on('connection', socket => { console.log('Huston ! we have a new connection ...'); }) So let's discuss the preceding code, where we are simply doing the following: Importing express and creating a new express app. Using the power of object on the fly, we've included the socket.io package over a new sub-object over the express application. This integration makes our express application now support the usage of  socket.io over the Application. We're indicating that we want to use the public folder as our static files folder, which will host our HTML/CSS/Javascript/IMG resources. We're listening to the connection, which will be fired once we have a new upcoming client. Once a new connection is up, we're printing a friendly message over our console. Let's configure our frontend. Head directly to your index.html files located in the public folder, and add the following line at the head of your page: <script src="/socket.io/socket.io.js"></script> The socket.io.js file will be served in application launch time, so don't worry much if you don't have one locally. Then, at the bottom of our index.html file before the closing of our <body> tag, add the following: <script> var socket = io.connect('localhost:3000'); </script> In the preceding script, we're connecting our frontend to our socket.io backend. Supposedly, our server is in port 3000; this way, we ensured that our two applications are running in sync. Head to your app.js files--created in the earlier recipes; create and import it if you didn't do so already--and introduce the following: //[*] Importing Firebase Needed Dependencies importScripts('https://www.gstatic.com/firebasejs/ 3.5.2/firebase-app.js'); importScripts('https://www.gstatic.com/firebasejs/ 3.5.2/firebase-messaging.js'); // [*] Firebase Configurations var config = { apiKey: "", authDomain: "", databaseURL: "", storageBucket: "", messagingSenderId: "" }; //[*] Initializing our Firebase Application. firebase.initializeApp(config); // [*] Initializing the Firebase Messaging Object. const messaging = firebase.messaging(); Everything is great; don't forget to import the app.js file within your index.html file. We will now see how we can grab our registration_id token next: As I explained earlier, the registration token is unique per browser. However, in order to get it, you should know that this token is considered a privacy issue. To ensure that they do not fall into the wrong hands, it's not available everywhere and to get it, you need to ask for the Browser User Permission. Since you can use it in any particular application, let's see how we can do that. The registration_id token will be considered as security and privacy threat to the user in case this token has been compromised, because once the attacker or the hacker gets the tokens, they can send or spam users with push messages that might have a malicious intent within, so safely keeping and saving those tokens is a priority. Now, within your app.js files that we created early on, let's add the following lines of code underneath the Firebase messaging reference: messaging.requestPermission() .then(() => { console.log("We have permission !"); return messaging.getToken(); }) .then((token) => { console.log(token); socket.emit("new_user", token); }) .catch(function(err) { console.log("Huston we have a problem !",err); }); We've sent out token using the awesome feature of socket.io. In order to get it now, let's simply listen to the same event and hope that we will get some data over our NodeJS backend. We will now proceed to learn about receiving registration token: Back to the app.js file, inside our connection event, let's add the following code: socket.on('new_user', (endpoint) => { console.log(endpoint); //TODO : Add endpoint aka.registration_token, to secure place. }); Our socket.io logic will look pretty much as shown in the following code block: // [*] Configuring our Socket Connection. app.io.on('connection', socket => { console.log('Huston ! we have a new connection ...'); socket.on('new_user', (endpoint) => { console.log(endpoint); //TODO : Add endpoint aka.registration_token, to secure place. }); }); Now, we have our bidirectional connection set. Let's grab that regitration_token and save it somewhere safe for further use. How it works... In the first part of the recipe, we did the following: Importing using importScripts considering it a script tag with src attribute in HTML, the firebase app, and messaging libraries. Then, we're introducing our Firebase Config object. We've already discussed where you can grab that object content in the previous chapters. Initializing our Firebase app with our config file. Creating a new reference from firebase.messaging library--always remember that everything in Firebase starts with a reference. Let's discuss what we did previously in the section where we talked about getting the registration_token value: We're using the Firebase messaging reference that we created earlier and executing the requestPermission() function, which returns a promise. Next--assuming that you're following along with this recipe--you will do the following over your page. After launching the development server, you will get a request from your page (Figure 1): Now, let's get back to the code. If we allow the notification, the promise resolver will be executed and then we will return the registration_token value from themessaging.getToken(). Then, we're sending that token over a socket and emitting that with an even name of new_user. Socket.io uses web sockets and like we explained before, sockets are event based. So in order to have a two-way connection between nodes, we need to emit, that is, send an event after giving it a name and listening to the same event with that name. Remember the socket.io event's name because we'll incorporate that into our further recipes. Implementing sending/receiving registration using post requests In a different approach from the one used in Socket.io, let's explore the other way around using post requests. This means that we'll use a REST API that will handle all that for us. At the same time, it will handle saving the registration_token value in a secure place as well. So let's see how we can configure that. How to do it... First, let's start writing our REST API. We will do that by creating an express post endpoint. This endpoint will be porting our data to the server, but before that, let's install some dependencies using the following line: ~> npm install express body-parser --save Let's discuss what we just did: We're using npm to download ExpressJS locally to our development directory. Also, we're downloading body-parser. This is an ExpressJS middleware that will host all post requests data underneath the body subobject. This module is quite a common package in the NodeJS community, and you will find it pretty much everywhere. Now, let's configure our application. Head to the app.js file and add the following code lines there: const express = require('express'); const app = express(); const bodyParser = require('body-parser'); // [*] Configuring Body Parser. app.use(bodyParser.json()); // [*] Configuring Routes. app.post('/regtoken', (req, res) => { let reg_token =req.body.regtoken; console.log(reg_token); //TODO : Create magic while saving this token in secure place. }); In the preceding code, we're doing the following: Importing our dependencies including ExpressJS and BodyParser. In the second step, we're registering the body parser middleware. You can read more about body parser and how to properly configure it to suit your needs from https://github.com/expressjs/body-parser. Next, we're creating an express endpoint or a route. This route will host our custom logic to manage the retrieval of the registration token sent from our users. Now, let's see how we can send the registration token to form our user's side. In this step, you're free to use any HTTP client you seek. However, in order to keep things stable, we'll use the browser native fetch APIs. Since we've managed to fully configure our routes, it can host the functionality we want. Let's see how we can get the registration_token value and send it to our server using post request and the native browser HTTP client named fetch: messaging.requestPermission() .then(() => { console.log("We have permission !"); return messaging.getToken(); }) .then((token) => { console.log(token); //[*] Sending the token fetch("http://localhost:3000/regtoken", { method: "POST" }).then((resp) => { //[*] Handle Server Response. }) .catch(function(err) { //[*] Handle Server Error. }) }) .catch(function(err) { console.log("Huston we have a problem !", err); }); How it works... Let's discuss what we just wrote in the preceding code: We're using the Firebase messaging reference that we created earlier and executing the requestPermission() function that returns a promise. Next, supposing that you're following along with this recipe, after launching the development server you will get the following authorization request from your page: Moving back to the code, if we allow the notification, the promise resolver will be executed and then we will return the registration_token value from the messaging.getToken(). Next, we're using the Fetch API given it a URL as a first parameter and a method name that is post and handling the response and error. Since we saw the different approaches to exchange data between the client and the server, in the next recipe, we will see how we can receive web push notification messages from the server. Receiving web push notification messages We can definitely say that things are on a good path. We managed to configure our message to the server in the past recipes. Now, let's work on getting the message back from the server in a web push message. This is a proven way to gain more leads and regain old users. It is a sure way to re-engage your users, and success stories do not lie. Facebook, Twitter, and e-commerce websites are the living truth on how a web push message can make a difference in your ecosystem and your application in general. How to do it... Let's see how we can unleash the power of push messages. The API is simple and the way to do has never been easier, so let's how we can do that! Let's write down the following code over our firebase-messaging-sw.js file: // [*] Special object let us handle our Background Push Notifications messaging.setBackgroundMessageHandler(function(payload) { return self.registration.showNotification(payload.data.title, body: payload.data.body); }); Let's explain the preceding code: We're using the already created messaging object created using the Firebase messaging library, and we're calling. the setBackgroundMessageHandler() function. This will mean that we will catch all the messages that we will keep receiving in the background. We're using the service worker object represented in the self-object, and we're calling the showNotification() function and passing it some parameters. The first parameter is the title, and we're grabbing it from the server; we'll see how we can get it in just a second. The second parameter is the body of the message. Now, we've prepared our frontend to received messages. Let's send them from the server, and we will see how we can do that using the following code: var fcm = new FCM('<FCM_CODE>'); var message = { to: data.endpoint, // required fill with device token or topics notification: { title: data.payload.title, body: data.payload.body } }; fcm.send(message) .then(function(response) { console.log("Successfully sent with response: ", response); }) .catch(function(err) { console.log("Something has gone wrong!"); console.error(err); }) }); The most important part is FCM_CODE. You can grab it in the Firebase console by going to the Firebase Project Console and clicking on the Overview tab (Figure 3): Then, go to the CLOUD MESSAGING tab and copy and paste the Server Key in the section (Figure 4): How it works... Now, let's discuss the code that what we just wrote: The preceding code can be put everywhere, which means that you can send push notifications in every part of your application. We're composing our notification message by putting the registration token and the information we want to send. We're using the fcm.send() method in order to send our notification to the wanted users. Congratulations! We're done; now go and test your awesome new functionality! Implementing custom notification messages In the previous recipes, we saw how we can send a normal notification. Let's add some controllers and also learn how to add some pictures to it so that we can prettify it a bit. How to do it... Now write the following code and add it to our earlier code over the messaging.setBackgroundMessageHandler() function. So, the end result will look something like this: // [*] Special object let us handle our Background Push Notifications messaging.setBackgroundMessageHandler(function(payload) { const notificationOptions = { body: payload.data.msg, icon: "images/icon.jpg", actions: [ { action : 'like', title: 'Like', image: '<link-to-like-img>' }, { action : 'dislike', title: 'Dislike', image: '<link-to-like-img>' } ] } self.addEventListener('notificationclick', function(event) { var messageId = event.notification.data; event.notification.close(); if (event.action === 'like') { console.log("Going to like something !"); } else if (event.action === 'dislike') { console.log("Going to dislike something !"); } else { console.log("wh00t !"); } }, false); return self.registration.showNotification( payload.data.title,notificationOptions); }); How it works... Let's discuss what we've done so far: We added the notificationOptions object that hosts some of the required metadata, such as the body of the message and the image. Also, in this case, we're adding actions, which means we'll add custom buttons to our notification message. These will range from title to image, the most important part is the action name. Next, we listened on notificationclick, which will be fired each time one of the actions will be selected. Remember the action field we added early on; it'll be the differentiation point between all actions we might add. Then, we returned the notification and showed it using the showNotification() function. We saw how to build powerful progressive applications using Firebase. If you've enjoyed reading this tutorial, do check out, 'Firebase Cookbook', for creating serverless applications with Firebase Cloud Functions or turning your traditional applications into progressive apps with Service workers. What is a progressive web app? Windows launches progressive web apps… that don’t yet work on mobile Hybrid Mobile apps: What you need to know
Read more
  • 0
  • 0
  • 28801

article-image-building-first-vue-js-web-application
Kunal Chaudhari
17 Apr 2018
11 min read
Save for later

Building your first Vue.js 2 Web application

Kunal Chaudhari
17 Apr 2018
11 min read
Vue is a relative newcomer in the JavaScript frontend landscape, but a very serious challenger to the current leading libraries. It is simple, flexible, and very fast, while still providing a lot of features and optional tools that can help you build a modern web app efficiently. In today’s tutorial, we will explore Vue.js library and then we will start creating our first web app. Why another frontend framework? Its creator, Evan You, calls it the progressive framework. Vue is incrementally adoptable, with a core library focused on user interfaces that you can use in existing projects You can make small prototypes all the way up to large and sophisticated web applications Vue is approachable-- beginners can pick up the library easily, and confirmed developers can be productive very quickly Vue roughly follows a Model-View-ViewModel architecture, which means the View (the user interface) and the Model (the data) are separated, with the ViewModel (Vue) being a mediator between the two. It handles the updates automatically and has been already optimized for you. Therefore, you don't have to specify when a part of the View should update because Vue will choose the right way and time to do so. The library also takes inspiration from other similar libraries such as React, Angular, and Polymer. The following is an overview of its core features: A reactive data system that can update your user interface automatically, with a lightweight virtual-DOM engine and minimal optimization efforts, is required Flexible View declaration--artist-friendly HTML templates, JSX (HTML inside JavaScript), or hyperscript render functions (pure JavaScript) Composable user interfaces with maintainable and reusable components Official companion libraries that come with routing, state management, scaffolding, and more advanced features, making Vue a non-opinionated but fully fleshed out frontend framework Vue.js - A trending project Evan You started working on the first prototype of Vue in 2013, while working at Google, using Angular. The initial goal was to have all the cool features of Angular, such as data binding and data-driven DOM, but without the extra concepts that make a framework opinionated and heavy to learn and use. The first public release was published on February 2014 and had immediate success the very first day, with HackerNews frontpage, /r/javascript at the top spot and 10k unique visits on the official website. The first major version 1.0 was reached in October 2015, and by the end of that year, the npm downloads rocketed to 382k ytd, the GitHub repository received 11k stars, the official website had 363k unique visitors, and the popular PHP framework Laravel had picked Vue as its official frontend library instead of React. The second major version, 2.0, was released in September 2016, with a new virtual DOM- based renderer and many new features such as server-side rendering and performance improvements. This is the version we will use in this article. It is now one of the fastest frontend libraries, outperforming even React according to a comparison refined with the React team. At the time of writing this article, Vue was the second most popular frontend library on GitHub with 72k stars, just behind React and ahead of Angular 1. The next evolution of the library on the roadmap includes more integration with Vue-native libraries such as Weex and NativeScript to create native mobile apps with Vue, plus new features and improvements. Today, Vue is used by many companies such as Microsoft, Adobe, Alibaba, Baidu, Xiaomi, Expedia, Nintendo, and GitLab. Compatibility requirements Vue doesn't have any dependency and can be used in any ECMAScript 5 minimum- compliant browser. This means that it is not compatible with Internet Explorer 8 or less, because it needs relatively new JavaScript features such as Object.defineProperty, which can't be polyfilled on older browsers. In this article, we are writing code in JavaScript version ES2015 (formerly ES6), so you will need a modern browser to run the examples (such as Edge, Firefox, or Chrome). At some point, we will introduce a compiler called Babel that will help us make our code compatible with older browsers. One-minute setup Without further ado, let's start creating our first Vue app with a very quick setup. Vue is flexible enough to be included in any web page with a simple script tag. Let's create a very simple web page that includes the library, with a simple div element and another script tag: <html> <head> <meta charset="utf-8"> <title>Vue Project Guide setup</title> </head> <body> <!-- Include the library in the page --> <script src="https://unpkg.com/vue/dist/vue.js"></script> <!-- Some HTML --> <div id="root"> <p>Is this an Hello world?</p> </div> <!-- Some JavaScript →> <script> console.log('Yes! We are using Vue version', Vue.version) </script> </body> </html> In the browser console, we should have something like this: Yes! We are using Vue version 2.0.3 As you can see in the preceding code, the library exposes a Vue object that contains all the features we need to use it. We are now ready to go. Creating an app For now, we don't have any Vue app running on our web page. The whole library is based on Vue instances, which are the mediators between your View and your data. So, we need to create a new Vue instance to start our app: // New Vue instance var app = new Vue({ // CSS selector of the root DOM element el: '#root', // Some data data () { return { message: 'Hello Vue.js!', } }, }) The Vue constructor is called with the new keyword to create a new instance. It has one argument--the option object. It can have multiple attributes (called options). For now, we are using only two of them. With the el option, we tell Vue where to add (or "mount") the instance on our web page using a CSS selector. In the example, our instance will use the <div id="root"> DOM element as its root element. We could also use the $mount method of the Vue instance instead of the el option: var app = new Vue({ data () { return { message: 'Hello Vue.js!', } }, }) // We add the instance to the page app.$mount('#root') Most of the special methods and attributes of a Vue instance start with a dollar character. We will also initialize some data in the data option with a message property that contains a string. Now the Vue app is running, but it doesn't do much, yet. You can add as many Vue apps as you like on a single web page. Just create a new Vue instance for each of them and mount them on different DOM elements. This comes in handy when you want to integrate Vue in an existing project. Vue devtools An official debugger tool for Vue is available on Chrome as an extension called Vue.js devtools. It can help you see how your app is running to help you debug your code. You can download it from the Chrome Web Store (https://chrome.google.com/webstore/ search/vue) or from the Firefox addons registry (https://addons.mozilla.org/en-US/ firefox/addon/vue-js-devtools/?src=ss). For the Chrome version, you need to set an additional setting. In the extension settings, enable Allow access to file URLs so that it can detect Vue on a web page opened from your local drive: On your web page, open the Chrome Dev Tools with the F12 shortcut (or Shift + command + c on OS X) and search for the Vue tab (it may be hidden in the More tools... dropdown). Once it is opened, you can see a tree with our Vue instance named Root by convention. If you click on it, the sidebar displays the properties of the instance: You can drag and drop the devtools tab to your liking. Don't hesitate to place it among the first tabs, as it will be hidden in the page where Vue is not in development mode or is not running at all. You can change the name of your instance with the name option: var app = new Vue({ name: 'MyApp', // ...         }) This will help you see where your instance in the devtools is when you will have many more: Templates make your DOM dynamic With Vue, we have several systems at our disposal to write our View. For now, we will start with templates. A template is the easiest way to describe a View because it looks like HTML a lot, but with some extra syntax to make the DOM dynamically update very easily. Displaying text The first template feature we will see is the text interpolation, which is used to display dynamic text inside our web page. The text interpolation syntax is a pair of double curly braces containing a JavaScript expression of any kind. Its result will replace the interpolation when Vue will process the template. Replace the <div id="root"> element with the following: <div id="root"> <p>{{ message }}</p> </div> The template in this example has a <p> element whose content is the result of the message JavaScript expression. It will return the value of the message attribute of our instance. You should now have a new text displayed on your web page--Hello Vue.js!. It doesn't seem like much, but Vue has done a lot of work for us here--we now have the DOM wired with our data. To demonstrate this, open your browser console and change the app.message value and press Enter on the keyboard: app.message = 'Awesome!' The message has changed. This is called data-binding. It means that Vue is able to automatically update the DOM whenever your data changes without requiring anything from your part. The library includes a very powerful and efficient reactivity system that keeps track of all your data and is able to update what's needed when something changes. All of this is very fast indeed. Adding basic interactivity with directives Let's add some interactivity to our otherwise quite static app, for example, a text input that will allow the user to change the message displayed. We can do that in templates with special HTML attributes called directives. All the directives in Vue start with v- and follow the kebab-case syntax. That means you should separate the words with a dash. Remember that HTML attributes are case insensitive (whether they are uppercase or lowercase doesn't matter). The directive we need here is v-model, which will bind the value of our <input> element with our message data property. Add a new <input> element with the v-model="message" attribute inside the template: <div id="root"> <p>{{ message }}</p> <!-- New text input --> <input v-model="message" /> </div> Vue will now update the message property automatically when the input value changes. You can play with the content of the input to verify that the text updates as you type and the value in the devtools changes: There are many more directives available in Vue, and you can even create your own. To summarize, we quickly set up a web page to get started using Vue and wrote a simple app. We created a Vue instance to mount the Vue app on the page and wrote a template to make the DOM dynamic. Inside this template, we used a JavaScript expression to display text, thanks to text interpolations. Finally, we added some interactivity with an input element that we bound to our data with the v-model directive. You read an excerpt from a book written by Guillaume Chau, titled Vue.js 2 Web Development Projects. Its a project-based, practical guide to get hands-on into Vue.js 2.5 development by building beautiful, functional and performant web. Why has Vue.js become so popular? Building a real-time dashboard with Meteor and Vue.js      
Read more
  • 0
  • 0
  • 28447
Modal Close icon
Modal Close icon