Categories
Angular Development

AngularJS Interview Questions asked In 2019

AngularJS, the ‘Swiss army knife’ of the developer community, has been seeing exponential growth in popularity and career opportunities in the recent years. No surprises there, as the development framework is known for its ability to create single-page web applications that encompass three critical components – speed, agility and a strong community backing it up. AngularJS continues to dominate the arena of Javascript framework and has proved itself to be a worthy investment for web developers who seek to fast-track their career. To help you get started, we have compiled a list of the most frequently asked AngularJS interview questions that will help you ace the AngularJS interviews that come your way.

AngularJS Interview Questions:

1. What is the difference between Angular and jQuery?

FeaturesjQueryAngular
DOM ManipulationYesYes
RESTful APINoYes
Animation SupportYesYes
Deep Linking RoutingNoYes
Form ValidationNoYes
2 Way Data BindingNoYes
AJAX/JSONPYesYes

2. Name the key features of AngularJS?

The key features of AngularJS are:

  • Scope
  • Controller
  • Model
  • View
  • Services
  • Data Binding
  • Directives
  • Filters
  • Testable

3. Explain data binding in AngularJS.

According to AngularJS.org, “Data-binding in Angular apps is the automatic synchronization of data between the model and view components. The way that Angular implements data-binding lets you treat the model as the single-source-of-truth in your application. The view is a projection of the model at all times. When the model changes, the view reflects the change and vice versa.”

There are two ways of data binding:

  1. Data mining in classical template systems
  2. Data binding in angular templates

4. What are directives in AngularJS?

A core feature of AngularJS, directives are attributes that allow you to invent new HTML syntax, specific to your application. They are essentially functions that execute when the Angular compiler finds them in the DOM.  Some of the most commonly used directives are ng-app,ng-controller and ng-repeat.

The different types of directives are:

  • Element directives
  • Attribute directives
  • CSS class directives
  • Comment directives

5. What are Controllers in AngularJS?

Controllers are Javascript functions which provide data and logic to HTML UI. As the name suggests, they control how data flows from the server to HTML UI.

6. What is Angular Expression? How do you differentiate between Angular expressions and JavaScript expressions?

Angular expressions are code snippets that are usually placed in binding such as {{ expression }} similar to JavaScript.

The main differences between Angular expressions and JavaScript expressions are:

  • Context: The expressions are evaluated against a scope object in Angular, while Javascript expressions are evaluated against the global window
  • Forgiving: In Angular expression, the evaluation is forgiving to null and undefined whereas in JavaScript undefined properties generate TypeError or ReferenceError
  • No Control Flow Statements: We cannot use loops, conditionals or exceptions in an Angular expression
  • Filters: In Angular, unlike JavaScript, we can use filters to format data before displaying it

7. What is the difference between link and compile in Angular.js?

  • Compile function is used for template DOM Manipulation and to collect all the directives.
  • Link function is used for registering DOM listeners as well as instance DOM manipulation and is executed once the template has been cloned.

8. What are the characteristics of ‘Scope’?

Scope is an object that refers to the application model. It is an execution context for expressions. Scopes are arranged in hierarchical structure which mimic the DOM structure of the application. Scopes can watch expressions and propagate events. The characteristics of Scope are:

  • Scopes provide APIs ($watch) to observe model mutations.
  • Scopes provide APIs ($apply) to propagate any model changes through the system into the view from outside of the “Angular realm” (controllers, services, Angular event handlers).
  • Scopes can be nested to limit access to the properties of application components while providing access to shared model properties. Nested scopes are either “child scopes” or “isolate scopes”. A “child scope” (prototypically) inherits properties from its parent scope. An “isolate scope” does not. See isolated scopes for more information.
  • Scopes provide context against which expressions are evaluated. For example {{username}} expression is meaningless, unless it is evaluated against a specific scope which defines the username property.

9. What are the advantages of using Angular.js framework?

Angular.js framework has the following advantages:

  • Supports two way data-binding
  • Supports MVC pattern
  • Support static template and angular template
  • Can add custom directive
  • Supports REST full services
  • Supports form validations
  • Support both client and server communication
  • Support dependency injection
  • Applying Animations
  • Event Handlers

10. What is the difference between AngularJS and backbone.js?

AngularJS combines the functionalities of most third party libraries and supports individual functionalities required to develop HTML5 Apps.  While Backbone.js does these jobs individually.

11. Explain what is injector in AngularJS?

An injector is a service locator, used to retrieve object instance as defined by provider, instantiate types, invoke methods, and load modules.

12. What is factory method in AngularJS?

Factory method is used for creating a directive.  It is invoked when the compiler matches the directive for the first time. We can invoke the factory method using $injector.invoke.

Syntax: module.factory( 'factoryName', function );
Result: When declaring factoryName as an injectable argument you will be provided with the value that is returned by invoking the function reference passed to module.factory.

13. What is ng-app, ng-init and ng-model?

  • ng-app : Initializes application.
  • ng-model : Binds HTML controls to application data.
  • ng-Controller : Attaches a controller class to view.
  • ng-repeat : Bind repeated data HTML elements. Its like a for loop.
  • ng-if : Bind HTML elements with condition.
  • ng-show : Used to show the HTML elements.
  • ng-hide : Used to hide the HTML elements.
  • ng-class : Used to assign CSS class.
  • ng-src : Used to pass the URL image etc.

14. Does Angular use the jQuery library?

Yes, Angular can use jQuery if it’s present in the app when the application is being bootstrapped. If jQuery is not present in the script path, Angular falls back to its own implementation of the subset of jQuery that we call jQLite.

15. Can AngularJS have multiple ng-app directives in a single page?

No. Only one AngularJS application can be auto-bootstrapped per HTML document. The first ngApp found in the document will be used to define the root element to auto-bootstrap as an application. If another ng-app directive has been placed then it will not be processed by AngularJS and we will need to manually bootstrap the second app, instead of using second ng-app directive.

16. Can angular applications (ng-app) be nested within each other?

No. AngularJS applications cannot be nested within each other.

17. What is internationalization and how to implement it in AngularJS?

Internationalization is a way in which you can show locale specific information on a website. AngularJS supports inbuilt internationalization for three types of filters: currency, date and numbers. To implement internalization, we only need to incorporate corresponding js according to locale of the country. By default it handles the locale of the browser.

18. On which types of component can we create a custom directive?

AngularJS provides support to create custom directives for the following:

  • Element directives − Directive activates when a matching element is encountered.
  • Attribute − Directive activates when a matching attribute is encountered.
  • CSS − Directive activates when a matching css style is encountered.
  • Comment − Directive activates when a matching comment is encountered.

19. What is $rootscope in AngularJS?

Every application has a single root scope. All other scopes are descendant scopes of the root scope. Scopes provide separation between the model and the view, via a mechanism for watching the model for changes. They also provide event emission/broadcast and subscription facility.

20. Can we have nested controllers in AngularJS?

Yes, we can create nested controllers in AngularJS. Nested controllers are defined in hierarchical manner while using in View.

21. What is bootstrapping in AngularJS?

Bootstrapping in AngularJS is nothing but initializing, or starting the Angular app. AngularJS supports automatic and manual bootstrapping.

  • Automatic Bootstrapping: this is done by adding ng-app directive to the root of the application, typically on the tag or tag if you want angular to bootstrap your application automatically. When angularJS finds ng-app directive, it loads the module associated with it and then compiles the DOM.
  • Manual Bootstrapping:Manual bootstrapping provides you more control on how and when to initialize your angular App. It is useful where you want to perform any other operation before Angular wakes up and compile the page.

22. What does SPA (Single Page Application) mean? How can we implement SPA with Angular?

Single Page Applications (SPAs) are web apps that load a single HTML page and dynamically update that page as the user interacts with the app. Since SPA the page never reloads, though parts of the page may refresh. This reduces the round trips to the server to a minimum.

It’s a concept where we create a single shell page or master page and load the webpages inside that master page instead of loading pages from the server by doing post backs. We can implement SPA with Angular using Angular routes. You can read up about SPAs here.

23. Why AngularJS?

AngularJS lets us extend HTML vocabulary for our application resulting in an expressive, readable, and quick to develop environment . Some of the advantages are:

  •     MVC implementation is done right.
  •     It extends HTML using directives, expression and data binding techniques to define a powerful HTML template.
  •     Two way data-binding, form validations, routing supports, inbuilt services.
  •     REST friendly.
  •     Dependency injection support.
  •     It helps you to structure and test your JavaScript code.

24. Is AngularJS compatible with all browsers?

Yes AngularJS is compatible with the following browsers: Safari, Chrome, Firefox, Opera 15, IE9 and mobile browsers (Android, Chrome Mobile, iOS Safari).

25. How to implement routing in AngularJS?

It is a five-step process:

  • Step 1: – Add the “Angular-route.js” file to your view.
  • Step 2: – Inject “ngroute” functionality while creating Angular app object.
  • Step 3: – Configure the route provider.
  • Step 4: – Define hyperlinks.
  • Step 5: – Define sections where to load the view.

26. Explain $q service, deferred and promises.

  • ‘Promises’ are post processing logics which are executed after some operation/action is completed whereas ‘deferred’ is used to control how and when those promise logics will execute.
  • We can think about promises as “WHAT” we want to fire after an operation is completed while deferred controls “WHEN” and “HOW” those promises will execute.
  • “$q” is the angular service which provides promises and deferred functionality.

Feeling overwhelmed with all the questions the interviewer might ask in your AngularJS interview? It’s never too late to strengthen your basics. Learn from industry experts on how to use AngularJS in real life use cases via a structured course.

Categories
Frontend Developers React Developers Resume

React Developer Job Description Template

React is a JavaScript library for building user interfaces. It has transformed the way we think about front-end development. React.js has clasped the engagement of the open-source community. And its demand is irreversible in the coming future. It is here to stay.

Here is the sample job specification for React.js developers which will help you outline the comprehensive job description and ensure that you efficiently find the right

ReactJs developer resume and hire the perfect fit.

ReactJs Job Description

Company Introduction

{{Write a short and catchy paragraph about your company. Make sure to provide information about the company’s culture, perks, and benefits. Mention office hours, remote working possibilities, and everything else that you think makes your company interesting.}}

Job Description:

We are looking for an experienced JavaScript developer who is proficient with React.js. The primary focus of the selected candidate would be on developing user interface components implementing and executing them following well-known React.js workflows (such as Flux or Redux). Also ensuring that these components and the overall application are robust and easy to manage. A commitment to collaborative problem solving, sophisticated design, and quality products are important.

Responsibilities:

  • Developing the latest user-facing features using React.js
  • Designing a modern highly responsive web-based user interface
  • Building reusable components and front-end libraries for future use
  • Translating designs and wireframes into high-quality code
  • Learn and understand user interactions
  • Optimizing components for maximum performance across a vast array of web-capable devices and browsers
  • Coordinating with various teams working on distinct layers
  • As a React.js Developer, you will be involved from conception to completion with projects that are technologically sound and aesthetically impressive. 
  • {{Add other relevant responsibilities here}}

Technical skills:

  • Strong proficiency in JavaScript, including DOM manipulation and the JavaScript object model
  • Thorough understanding of React.js and its core principles
  • Prior experience with popular React.js workflows (such as Flux or Redux)
  • Familiarity with more current specifications of EcmaScript
  • Prior experience with data structure libraries (e.g., Immutable.js)
  • Knowledge of isomorphic React is a plus
  • Familiarity with RESTful APIs
  • Familiarity with HTML / CSS
  • GIT experience is a plus
  • Knowledge of modern authorization mechanisms, such as JSON Web Token
  • Familiarity with modern front-end build pipelines and tools
  • Experience with common front-end development tools such as Babel, Webpack, NPM, etc.
  • Ability to understand business requirements and translate them into technical requirements
  • A knack for benchmarking and optimization
  • Familiarity with code versioning tools {{such as Git, SVN, and Mercurial}}
  • {{Make sure to mention any other framework, libraries, or other technology relevant to your project}}
  • {{List education level or certification you require}}

Non-technical skills:

  • Team player
  • Excellent time-management skills
  • Great interpersonal and communication skills
Categories
Node Top Coder

SequelizeJS Tutorial with Node: Popular Object relational mapping (ORM)

Background

Object Relational Mapping (ORM) is the process of mapping between objects and relational database systems. So it acts like an interface between two systems hiding details about an underlying mechanism. In this versatile world, database systems are also not 100% alike—the way of accessing data differs. When it comes to migration between databases, ORM could be an option if you want to avoid wasting time and effort. Here are some advantages of ORM over traditional query approach:

  • Developers can only focus on business logic rather than writing interfaces between code and db.
  • Reduces development time and costs by avoiding redundant codes
  • Capable of connecting to different databases, which comes handy during switching from one db to the other.
  • Helps to effectively query from multiple tables similar to SQL JOIN—ORM takes the responsibility of converting the object-oriented query approach to SQL queries.

Introduction

In this article, we will learn how to make an effective object-relational mapping with Sequelize in Node.js. There are a couple of other alternatives but this module is my favorite. Sequelize is easy to learn and has dozens of cool features like synchronization, association, validation, etc. It also has support for PostgreSQL, MySQL, MariaDB, SQLite, and MSSQL.

How to start ?

So our objective here is to understand its functionality by creating a sample application which will perform some basic operations with CRUD. I assume you have Node.js and PostgresSQL installed.

Starter app

Let’s use “express application generator” to create a starter application.

npm install express-generator -g
express testapp

To install sequelize, postgres and ejs (template engine), navigate to root of your generated folder.

npm install --save sequelize
npm install --save pg pg-hstore
npm install --save ejs

We will use EJS for templating instead of Jade. So we can remove Jade related dependencies and files from the default Express-generated project.

DB connection and models

Connecting to postgres is as easy as a single line

var sequelize = new Sequelize('postgres://username:password@localhost:5432/db_name');

Models are the objects which represent tables in a database. They are the heart of ORM and we can define them with sequelize.define. Our User model looks like this:

var User = sequelize.define('user', {
  firstName: {
    type: DataTypes.STRING,
    allowNull: false,
    unique: 'compositeIndex'
  },
  lastName: {
    type: DataTypes.STRING,
    unique: 'compositeIndex'
  },
    .........
    .........
    .........
  dateJoined: {
    type: DataTypes.DATE,
    defaultValue: DataTypes.NOW
  }
}, {
  getterMethods   : {
    address: function()  { return this.state + ', ' + this.country }
  },
  setterMethods   : {
    address: function(value) {
      var names = value.split(', ');
      this.setDataValue('country', names[0]);
      this.setDataValue('state', names[1]);
    },
  }
});

You just need to define the columns and their data types and Sequelize will automatically add createdAt and updatedAt to your model. There are a few other settings you can also configure for your columns.

  • allowNull — Set false if null is not allowed
  • defaultValue — Set a default value for a column.
    Example: DataTypes.NOW for dateJoined column.
  • autoIncrement — Automatically increments the column by one every time a new row is inserted
  • comment — Mention a comment for your column
  • unique — Mention a boolean true to define a column as unique. For a composite key, a string can be mentioned for multiple columns.

Example

userId: {type: Sequelize.STRING, unique: true},
fullName: { type: Sequelize.STRING,  unique: 'compositeIndex'},
dob: { type: Sequelize.DATE, unique: 'compositeIndex'}

Getter and setter methods

In Sequelize, we can define pseudo properties on a model. These properties are not an actual part of the database schema, they are just for the models. In the example above, “address” is a pseudo-property, and its value is initialized through getter and setter methods. When state and country are fetched from db, Sequelize merges them with a comma to populate the “address” property (getterMethods). Similarly, when we set the address, it gets split into state and country (setterMethods). Thus, the “address” seems like a column in db but actually it’s not.

Preparing sample data

There are different approaches to create a new entry in DB. The first approach is to build a non persistent object and then call save() to persist the data.

var newUser = user.build({
  firstName: 'John', 
  lastName: 'Doe', 
  age: 28, 
  country: 'US', 
  state: 'Indiana', 
  email: 'johndoe@example.com'
});
newUser.save().then(function() {
  // Do stuffs after data persists
})

Another alternative is to do both the steps in a single line using user.create({.....}).then(function(user) {}). If we need to create bulk instances, here’s how we do it.

user.bulkCreate([USERS],{ validate: true }).then(function() {
  // Congratulate user!
}).catch(function(errors) {
  // Catch  if validation failed
  // Print errors
});

Check ./routes/createData.js in the sample project for the bulk creation logic. Go with the steps on localhost:3000 to see the operations live as we discuss further.

Querying data

We can query data using findAll and findOne which takes additional parameters like attributes, where condition, ordering, and pagination. Let’s learn these through examples.

Get first 100 user instances. The highlighted column in the image above comes from the “group” table.

user.findAll({limit: 100}).then(function(users) {
  // Send array to view
});

Get user by email

user.findOne({where : {email: 'johndoe@example.com'}}).then(function(user) {
  // Send user to view
});

A little more complex example. Find all users of California and Arizona whose age is in between 20 and 40 and last name contains ‘user’.

var query = {};
query.where = {
  $or: [
    {state: "California"},
    {state: "Arizona"}
  ],
  age: {
    $between: [20, 40]
  },
  lastName: {
    $ilike: '%user%'
  }
};
user.findAll(query).then(function(users) {
  // Do something awesome here
});	
SELECT "id", "firstName", "lastName", "email", "age", "country", "state", "dateJoined", "createdAt", "updatedAt"
FROM "user" AS "user"
WHERE ("user"."state" = 'California' OR "user"."state" = 'Arizona')
  AND "user"."age" BETWEEN 20 AND 40
  AND "user"."lastName" ILIKE '%user%';

If you need more operators for querying data, you can find the list here.

Sequelize also offers an option to directly provide SQL query, like:

sequelize.query(QUERY, { model: user }).then(function(users) {
  // Array of instance of user
})

Updates and destroy

Updating an instance can take two parameters, the updated values and where condition.

user.update({
  firstName: "John",
  lastName: "Doe",
  address: "Nevada, US"
},{
  where: { email : "johndoe@example.com" }
})
.then(function () { 

});

“Destroy” also takes a where condition (Check below). You can also follow the callback syntax (just like update) to do some logic after destroying.

user.destroy({
  where: {
    email: 'johndoe@example.com'
  }
});
// DELETE FROM user WHERE email = 'johndoe@example.com';

Relation and associations

In this section, we will learn about one-to-one association. When two models are linked to each other by a single foreign key, we say it as a one-to-one association. In our case, we have two models: user and group. Each user is associated with a single group. So the user model has a foreign key group_id which points to the groupIdof the group model. Defining this association is very easy in Sequelize.

user.belongsTo(group, {foreignKey: 'group_id', targetKey: 'groupId'});

Once the line above is executed, it creates a foreign key “group_id” for the group model. To read the data from both tables (like join in SQL), simply include the target model as follows:

user.findAll({
  limit: 100,
  include: [{
    model: group
  }]
}).then(function(users) {
  // Send users to view
});

Wrapping up

There are more features in Sequelize, such as transaction management, hooks, scopes, etc. Combining all these features Sequelize becomes a strong ORM module for Node.js. But when it comes to complex relations and associations, it seems a little dimmed and maintainability could be a concern. But other than that it is a bullet-proof module with a well-described documentation.

Categories
React Native Developers React Native Web

React-Native-Web tutorials: Your first hybrid app

Before we Start React-Native-Web

  • Basic understanding of React (understanding React native as well is preferred but not necessary)
  • Some understanding of ES6
  • Have npm installed on your machine
  • yarn install. If you don’t, feel free to substitute any instance of yarn add ... with npm install -S ....

Downloading Expo

Download the Expo XDE through the above link. Expo will save us the headache of running iOS/Android simulators on our machine. With Expo, you can create a React Native app and test it on your own phone. There is an CLI as well that you could use, but we’ll be using the XDE for this project. Once you’ve done that, open it and register an account if you haven’t already.

Expo on your Phone

Through the link, find and download Expo client for the mobile device (iOS version, or Android) on which you’ll be testing. Once it’s downloaded, log in using the same account you’re using with the XDE.

Create your app

Open theExpo XDE and click ‘create new project…’ to create an app. Use the blank template.

Run your app

  • Open the expo client on your device
  • Your project should appear under ‘Recently in Development’
  • Click it and wait while the Javacript bundle is built on your phone
  • You should see the following screen on your device
  • Change some text in App.js and save it, and your app should automatically reload with the updated text

2) Then Web

Dependencies

Let’s start by getting the necessary packages to run this on the web.

Open your terminal, navigate to the project folder and then run the following command:

yarn add react-scripts react-dom react-native-web react-art react-router-native react-router-dom

Here’s what we’re adding:

  • react-scripts: contains the scripts used in create-react-app.
  • react-dom: allows react-code to be rendered into an HTML page
  • react-native-web: the main source of magic in this app. This library will convert our react-native components into web elements. Thankfully, react-scripts is already configured to use it, so you won’t need to touch any Webpack yourself to get it up and running
  • react-art: a peer dependency for react-native-web
  • react-router-native: routing library for React Native
  • react-router-dom: routing library for React on the web

File Restructure

We need to have two separate entry points which point to the same root application. One App.js will be used by Expo, and the other src/index.jswill be used by react-scripts to be rendered on the web.

  • Create a folder called src and copy the existing App.js into it to create src/App.js
  • Refactor your root folder’s App.js so that it simply imports and renders the src/App.js that you just created
// /App.js
import React from 'react';
import HybridApp from './src/App';
const App = (props) => {
  return (
    <HybridApp />
  );
}
export default App;
  • Create a folder called public and create public/index.html
  • In your index.html simply make a html skeleton, with <div id="root"></div> in the body so that your app has somewhere to render
<!-- public/index.html -->
<!DOCTYPE html>
<html>
   <head>
      <meta charset="utf-8" />
      <title>Pokedex</title>
   </head>
   <body>
      <div id="root"></div>
   </body>
</html>
  • In your src folder, create index.js and write the following code to have it render your app into the DOM
// src/index.js
import React from 'react';
import ReactDom from 'react-dom';
import App from './App';
ReactDom.render(<App />, document.getElementById("root"));

Scripts

react-scripts is automatically configured to recognize React Native code and translate it using the react-native-web library that we imported. That’s why we can make this work without pulling our hair out over Webpack configurations. All we need to do now is set some scripts in our package.jsonso that we can easily run it.

Add the following property to your package.json

// package.json
"scripts": {
    "start-web": "react-scripts start",
    "build-web": "react-scripts build"
  },

Run it on the Web

In your terminal, run yarn start-web and in moments your web app should appear in the browser. Congratulations, you have created your first hybrid app!

Now let’s make this app do something.

Adding Content and Functionality

Let’s start off simple by adding a list of Pokemon.

To keep things simple, we’ll just store our list of Pokemon insrc/spokemonStore.js.

// src/pokemonStore.js
export default [
  {
    number: '1',
    name: 'Bulbasaur',
    photoUrl: 'https://assets.pokemon.com/assets/cms2/img/pokedex/full/001.png',
    type: 'grass'
  },
  {
    number: '4',
    name: 'Charmander',
    photoUrl: 'https://assets.pokemon.com/assets/cms2/img/pokedex/full/004.png',
    type: 'fire'
  },
  {
    number: '7',
    name: 'Squirtle',
    photoUrl: 'https://assets.pokemon.com/assets/cms2/img/pokedex/full/007.png',
    type: 'water'
  }
];

Instead of using map, we’ll follow React Native convention and use FlatList, as it will work just fine with react-native-web.

// src/App.js
import React, { Component } from 'react';
import { View, Text, FlatList, StyleSheet } from 'react-native';
import pokemon from './pokemonStore'
class App extends Component {
  render() {
    return (
      <View style={styles.container}>
        <FlatList
          keyExtractor={pokemon => pokemon.number}
          data={pokemon}
          renderItem={({ item }) => <Text>{item.name}</Text>}
        />
      </View>
    );
  }
}
const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
    marginTop: 50,
    padding: 50
  },
});
export default App;

Platform-Specific Styles

Note: It won’t be an issue for a barebones project like ours, but in your own projects, you may have to adjust the styles web layout so that it looks similar to your native app. To do so, you can create src/index.css with your web-specific adjustments and and import it into index.js.

/* src/index.css */
#root {
  /* layout adjustments for web app */
}

However, that will effect the layout of that app as a whole. Inevitably we need to figure out away to change specific parts of the app based on the platform, and this is where things get interesting.

Platform-Specific Code

We need to add some basic routing so that we can go from viewing a list of Pokemon to the details of a single Pokemon. react-router-dom is great for the web, and another library, react-router-native, is great for React Native. To keep our code clean, we will create a generic Routing.js file that will abstract that distinction and be available throughout our code.

We will create routing.web.js with components from one library and routing.native.js with similarly named equivalents from the other. Import statements to our routing files will omit the file extension, and because of that, the compiler will automatically import whichever one is relevant to the platform for which the app is being compiled and ignore the other.

This will allow us to avoid writing code that checks for the platform and uses the appropriate library every single time we use routing.

First create the web version of your routing file src/routing.web.js

export {
  BrowserRouter as Router,
  Switch,
  Route,
  Link
} from 'react-router-dom';

Then, the native version, src/routing.native.js .

export {
  NativeRouter as Router,
  Switch,
  Route,
  Link
} from 'react-router-native';

Now, create two files, Home.js and Pokemon.js . These will be the components rendered by your routes.

In Home.js, simply render a list of Pokemon like you did in App.js.

// src/Home.js
import React from 'react';
import { View, Text, FlatList } from 'react-native';
import pokemon from './pokemonStore';
const Home = props => {
  return (
    <View>
      <FlatList
        keyExtractor={pokemon => pokemon.number}
        data={pokemon}
        renderItem={({ item }) => <Text>{item.name}</Text>}
      />
    </View>
  );
};
export default Home;

In Pokemon.js render information about a single Pokemon. You can hard-code in one now as a placeholder. We’ll refactor and tie everything together after we’re sure that the routing works.

// src/Pokemon.js
import React from 'react';
import { View, Text, Image } from 'react-native';
import pokemon from './pokemonStore';
const Pokemon = props => {
  const examplePokemon = pokemon[0];
  return (
    <View>
      <View>
        <View>
          <Text>{`#${examplePokemon.number}`}</Text>
        </View>
        <View>
          <Text>{`Name: ${examplePokemon.name}`}</Text>
        </View>
        <View>
          <Text>{`Type: ${examplePokemon.type}`}</Text>
        </View>
        <View>
          <Image
            style={{ width: 50, height: 50 }}
            source={{ uri: examplePokemon.photoUrl }}
          />
        </View>
      </View>
    </View>
  );
};
export default Pokemon;

Now change your App.js so that it now simply renders your routes. One for each component. Make sure you pass in all of the route’s props into the component by adding {…props}. You’ll need that in order to access the ‘history’ prop which can be used to change routes.

// src/App.js
import React, { Component } from 'react';
import { View, StyleSheet } from 'react-native';
import { Router, Switch, Route } from './routing';
import Home from './Home';
import Pokemon from './Pokemon';
class App extends Component {
  render() {
    return (
      <View style={styles.container}>
        <Router>
          <Switch>
            <Route exact path="/" render={props => <Home {...props} />} />
            <Route path="/pokemon" render={props => <Pokemon {...props} />} />
          </Switch>
        </Router>
      </View>
    );
  }
}
const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
    marginTop: 50,
    padding: 50
  }
});
export default App;

Refresh your app and make sure that each route works by changing the address bar manually. Therefore, deliberately adding a ‘render’ prop instead of ‘component’ into each route because we’ll be passing in some props to each component as we render them.

Your root route will look the same as before. Type ‘localhost:3000/pokemon’ in your address bar and this what you should get:

Tying it all Together.

Now it’s time to add some logic to make this app work. We need to do the following:

  • In App.js, create a function called selectPokemon which takes a Pokemon as an argument and sets it to the App state as ‘selectedPokemon’. To prevent errors, set a default state with a ‘selectedPokemon’ set to null
  • Pass selectPokemon into Home.js through its props
  • In Home.js Wrap each Pokemon in the list in a <TouchableOpacity />component so that, once clicked, it can: a) Call selectPokemon and pass in the pokemon as an argument and b) call this.props.history.push(‘/pokemon’) in order to switch to the Pokemon route
  • In App.js, pass in a prop called selectedPokemon into the <Pokemon /> being rendered in the second route. It’s value should be this.state.selectedPokemon, which will be undefined until you select a Pokemon.
  • In the Pokemon component, remove the reference to the pokemonStore and instead refer to props.selectedPokemon. It would be a good idea to also add some default content that is conditionally shown if no Pokemon is selected.
  • Create View and some Text with the message ‘return to home’. To make it work, wrap it with a <Link/> Tag from your routing file and in that Link component, add the property ‘to=”/”’ to have it redirect to your home route.

Here are what your three changed files should now look like:

// src/App.js
import React, { Component } from 'react';
import { View, StyleSheet } from 'react-native';
import { Router, Switch, Route } from './routing';
import Home from './Home';
import Pokemon from './Pokemon';
class App extends Component {
  state = {
    selectedPokemon: null
  };
  selectPokemon = selectedPokemon => {
    this.setState({
      selectedPokemon
    });
  };
  render() {
    return (
      <View style={styles.container}>
        <Router>
          <Switch>
            <Route
              exact
              path="/"
              render={props => (
                <Home {...props} selectPokemon={this.selectPokemon} />
              )}
            />
            <Route
              path="/pokemon"
              render={props => (
                <Pokemon
                  {...props}
                  selectedPokemon={this.state.selectedPokemon}
                />
              )}
            />
          </Switch>
        </Router>
      </View>
    );
  }
}
const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
    marginTop: 50,
    padding: 50
  }
});
export default App;
// src/Home.js
import React from 'react';
import { 
  View,
  Text,
  FlatList,
  TouchableOpacity
} from 'react-native';
import pokemon from './pokemonStore';
const Home = props => {
  const handlePress = pokemon => {
    props.selectPokemon(pokemon);
    props.history.push('/pokemon');
  };
  return (
    <View>
      <FlatList
        keyExtractor={pokemon => pokemon.number}
        data={pokemon}
        renderItem={({ item }) => (
          <TouchableOpacity onPress={() => handlePress(item)}>
            <Text>{item.name}</Text>
          </TouchableOpacity>
        )}
      />
    </View>
  );
};
export default Home;
// src/Pokemon.js
import React from 'react';
import { View, Text, Image } from 'react-native';
import { Link } from './routing';
const Pokemon = props => {
  const backButton = (
    <View>
      <Link to="/">
        <Text>Go Back</Text>
      </Link>
    </View>
  );
  if (!props.selectedPokemon) {
    return (
      <View>
        {backButton}
        <Text>No Pokemon selected</Text>
      </View>
    );
  }
  const {
    selectedPokemon: { name, number, type, photoUrl }
  } = props;
  return (
    <View>
      <View>
        {backButton}
        <View>
          <Text>{`#${number}`}</Text>
        </View>
        <View>
          <Text>{`Name: ${name}`}</Text>
        </View>
        <View>
          <Text>{`Type: ${type}`}</Text>
        </View>
        <View>
          <Image style={{ width: 50, height: 50 }} source={{ uri: photoUrl }} />
        </View>
      </View>
    </View>
  );
};
export default Pokemon;

You’re done! and should now be able to load your app, see a list of Pokemon, click on one to see more it’s details, and then press ‘Go back’ to see your list again.

Bonus tip: Platform-Specific code — The ‘Share’ Button

I showed you how to separate code for different platforms by using different files. However, there will likely be times where you have plaftorm-specific logic that can be solved in such a simple way. For example, we’re going to show a ‘share’ button in our Pokemon view, but we only need it on mobile. It would be overkill to make two versions of that entire component just to hide or show one feature. Instead, we’ll simply hide the functionality where it’s not needed. React Native gives us access to a Platform object, which contains a property called ‘OS’ with a value that changes with the operating system of whichever platform your app is running on. We can use that to hide or show our ‘share’ button accordingly.


 // Make sure you import { Platform } from 'react-native';
handlePress = () => {
  Share.share({ 
    message: 'Check out my favorite Pokemon!',
    url: props.selectePokemon.photoUrl
  })
};
...
{ Platform.OS !== 'web' &&
  <View>
    <Button title="Share" onPress={this.handlePress}/>
  </View>
}

As our example is relatively simple, but building a universal React app will inevitably get tricky as you add scale and functionality, since many React Native libraries have little to no compatibility with the web, and even those that do will often require some tinkering with Webpack in order to work. And you should also keep in mind that Expo, as much as it significantly simplifies setup, adds some limitation to the libraries that you can work with. If you’d like to know details about compatibility with specific libraries, this list would be a great place to start:

https://native.directory
Categories
Development Top Coder

Gatsby and Cosmic JS tutorial for building documentation

What is Gatsby?

Gatsby is an easy to use framework for generating static web site files.  It comes bundled with all sorts of hotness, like React JS for building web components. And GraphQL for handling our component state without the need to configure something like Redux to handle external data

What about Cosmic JS?

Cosmic JS will handle our publishing and data storage.  It’s easy to set up and easy to implement for apps like this. Yet scalable enough to handle more complex projects across larger teams.  We will use this to create and store our documentation content.  This will us allowing us to focus on how our users interact with our app, and let Cosmic JS do all the heavy lifting.

Is that all?

Well no… we are going to convert our docs from markdown to html,  since that’s what web Browsers like.  To do this we are going to use a package called Showdown. that can handle parsing and converting markdown to and from HTML.

Any Requirements?

You will need to have access to a terminal, a Cosmic JS account with a bucket and a documentation object. The latest version of Node installed in order to install the necessary software to make this app work.  I’m going to be using yarn to run my build scripts but you can npm if you like.  Remember to choose npm or yarn and stick with it as things can get little hairy when it’s time to deploy.

Let’s Build!!

1.1 – Setting up our Development Environment

To get started we will want to install Gatsby and install our dependencies.  Easy peasy. Gatsby uses a handy command line interface (CLI) to build our initial project files.  First we will want to install the CLI by installing it globally with npm:

$ npm install -g gatsby-cli

This gives us access to the gatsby command and allows us to initialize our project.  Run the following script to create a new directory filled with a project template:

$ gatsby new gatsby-docs

Wait a second to allow the script to complete and you will notice a new directory created called gatsby-docs.   Let’s see what’s inside by changing directories:

$ cd gatsby-docs

Much of this will look familiar if are used to creating Node applications but some of this will be a little new. You should be able to get a development server up and running by executing the start script:

$ yarn start

After a second you should see a success prompt letting you know that everything has compiled properly and your app is live.

Now you can open up your browser pointing to localhost:8000 and see the compiled output.

Congrats! You have set up a working Gatsby site. But before we dig into what is going on under the covers let’s install the rest of our dependencies that will power our app:

$ yarn add cosmicjs showdown highlight.js dotenv node-sass gatsby-plugin-sass gatsby-source-graphql

Whoa… That’s a lot of newly installed packages, but each of these are super useful I swear.

  • cosmicjs will be used to add new content to our app.
  • showdown is the text parser I mentioned that will handle markdown and html conversion.
  • highlight.js is going to handle our syntax highlighting inside of our converted markdown text.
  • dotenv is an environment variable package that will make sure our sensitive tokens and/or runtime environment is configured from a .env file
  • node-sass and the gatsby-plugin-sass packages will allow to use .scss files to style our components.
  • gatsby-source-graphql will allow us to leverage GraphQL queries on external data (ie – use the Cosmic JS GraphQL api)

With all of that business out of the way. We can look at our directory and configure our Gatsby source code to run properly.

2.0 – Configuring Gatsby

Now we can dig into our directory and make sure Gatsby is configured properly. For using the technologies that will scalably and sensibly power our app.

The first file we will want to look into is gatsby-config.js.  This file is used to configure high level plugins, that allow source code to be bundled properly when static files built.  It also contains bit of metadata that describes our site to users and can be queried in our React Components.

Here we will add our newly installed plugins to the default configuration you see before you.  First we just need to add gatsby-plugin-sass to the plugins list, allowing us to import sass files and leverage sass to write sensible styling specs for each component.

Next up we will add an object to end of our plugins list for gatsby-source-graphql  that will configure our external GraphQL API endpoint to allow us to fetch data from Cosmic JS.  Here’s how things should look:


module.exports = {
  siteMetadata: {
    title: `Gatsby Docs`,
    description: `Create and View Minimalistic Documentation, powered by GatsbyJs and CosmicJS`,
    author: `@jacobknaack`,
  },
  plugins: [
    `gatsby-plugin-eslint`,
    `gatsby-plugin-react-helmet`,
    `gatsby-transformer-sharp`,
    `gatsby-plugin-sharp`,
    `gatsby-plugin-sass`,
    {
      resolve: `gatsby-plugin-manifest`,
      options: {
        name: `gatsby-docs`,
        short_name: `docs`,
        start_url: `/`,
        display: `minimal-ui`,
        icon: `src/images/gatsby-icon.png`, // This path is relative to the root of the site.
      },
    },
    {
      resolve: `gatsby-source-graphql`,
      options: {
        url: `https://graphql.cosmicjs.com/v1`,
        fieldName: `docs`,
        typeName: `Doc`,
        refetchInterval: 10,
      },
    },
    // this (optional) plugin enables Progressive Web App + Offline functionality
    // To learn more, visit: https://gatsby.app/offline
    // 'gatsby-plugin-offline',
  ],
}

Now we are set to make GraphQL queries to the Cosmic JS GraphQL API!  Next, Let’s talk for a second about Gatsby and how things are going to break down.

2.1 Building our app with Gatsby

I’ve mentioned that Gatsby is a static site generator, but what does that mean?  Gatsby takes all the fancy code we create and produces static files that are pre-configured using the config files we specify.  By doing so we get increased performance for sites that may have lots of images, data to be fetched, and other assets that can slow down web applications.

Let’s now get some source code created.  Our site is going to use just two ‘Pages’, one that will serve a home page to list the documentation we’ve created, and one for viewing a piece of documentation.  But to fetch the content that we are going to display, we are going to use GraphQL, which we have recently configured.  We will need to add some variables to our gatsby-node.js file in order to allow our static files to have the necessary parameters to make API calls.

Create a .env file and add your Cosmic JS environment variables

In your Cosmic JS Bucket > Basic Settings menu you will see fields for a bucket-slug and read and write keys down at the bottom.  Copy all three of these things and add them to a .env file.

At your project root, type into your terminal:

$ touch .env

Now Create three lines:

COSMIC_BUCKET=your-bucket-slug
COSMIC_READ_KEY=your-read-key
COSMIC_WRITE_KEY=your-write-key

We will use these with our dotenv package to allow our src files to access these variables when necessary.

Open up gatsby-node.js and add config variables to pages

We are now going to use Gatsby’s built in node API to give each page in our site access to the environment variable we just created.  First we will import the variables from our .env file using dotenv, then we will explicitly set each variable in our page’s context. Your file should look like this:

require("dotenv").config();
/**
 * Implement Gatsby's Node APIs in this file.
 *
 * See: https://www.gatsbyjs.org/docs/node-apis/
 */

exports.onCreatePage = ({ page, actions }) => {
  const { createPage, deletePage } = actions

  deletePage(page)
  createPage({
    ...page,
    context: {
      writeKey: `${process.env.COSMIC_WRITE_KEY}`,
      readKey: `${process.env.COSMIC_READ_KEY}`,
      cosmicBucket: `${process.env.COSMIC_BUCKET}`
    }
  })
}

Creating our first page

Now we are going to create our first page that will grab all of the documentation objects and display them at the root of our site,  on index.js.  First let’s create our list by creating a folder in the components directory titled docs – /src/components/docs/ and in that folder we will create a file titled index.js.

This will be our module that is first displayed when we render our page after fetching our docs.  Here is the source code:


import React from 'react'import React from 'react'
import PropTypes from 'prop-types'
import { Link } from 'gatsby'

// formats our slugs to be used in links to our display page
function formatSlug(title) {
  return title
    .toLowerCase()
    .replace(/[^a-zA-Z ]/g, "")
    .replace(/\s/g, '-')
}

// formats datestrings into an object so that they can
// easily be used for display
function formatDate(dateString) {
  const date = new Date(dateString)
  const months = [
    'January',
    'February',
    'March',
    'April',
    'May',
    'June',
    'July',
    'August',
    'September',
    'October',
    'November',
    'December',
  ]
  const hh = date.getHours()
  let minutes = date.getMinutes()
  let hour = hh
  let dayTime = 'AM'
  if (hour >= 12) {
    hour = hh - 12
    dayTime = 'PM'
  }
  if (hour == 0) {
    hour = 12
  }

  minutes = minutes < 10 ? '0' + minutes : minutes

  return {
    year: date.getFullYear(),
    month: months[date.getMonth()],
    date: date.getDate(),
    hour: hour,
    minutes: minutes,
    dayTime: dayTime,
  }
}

const Docs = ({ docs }) => (
  <div className="docs-container">
    <div className="docs-list">
      {docs.map(doc => {
        const date_created = formatDate(doc.created_at)
        return (
          <Link
            key={doc._id}
            to={`/doc/${formatSlug(doc.title)}`}
            className="docs-item"
          >
            <div className="date-container">
              <h3 className="date-yearMonthDate">{`${date_created.month} ${
                date_created.date
                }, ${date_created.year}`}</h3>
              <p className="date-timeDayTime">{`at ${date_created.hour}:${
                date_created.minutes
                } ${date_created.dayTime}`}</p>
            </div>
            <h2 className="doc-title">{doc.title}</h2>
            <div
              className="doc-preview"
              dangerouslySetInnerHTML={{
                __html: doc.content,
              }}
            />
          </Link>
        )
      })}
    </div>
  </div>
)

Docs.propTypes = {
  docs: PropTypes.array.isRequired,
  pageContext: PropTypes.object,
}

export default Docs

What’s going on here:

This page basically runs a big loop over our docs  and returns some fancy jsx.  We map through the docs array and produce a Link from Gatsby that will contain the title, a date, and some content that uses a a description for the piece of documentation that was published.

Feel free to add any .scss files to this directory as well to get a styling that works for you for the given class names.

Update the ‘home’ page with our new components

Now we can open up our home page file at /pages/index.js and import the components we just created and add them to our returned jsx.


import React from 'react'
import PropTypes from 'prop-types'
import { graphql } from 'gatsby'

import Layout from '../components/layout'
import SEO from '../components/seo'
import Docs from '../components/docs'

const IndexPage = ({ data, pageContext }) => {
  return (
    <Layout>
      <SEO
        title="Home"
        keywords={[
          `gatsby`,
          `application`,
          `react`,
          'documentation',
          'docs',
          'markdown',
        ]}
      />
      <Docs docs={data.docs.objectsByType} pageContext={pageContext} />
    </Layout>
  )
}

IndexPage.propTypes = {
  data: PropTypes.object,
  pageContext: PropTypes.object,
}

export const query = graphql`
  query($cosmicBucket: String!, $readKey: String!) {
    docs {
      objectsByType(
        bucket_slug: $cosmicBucket
        type_slug: "docs"
        read_key: $readKey
      ) {
        title
        content
        created_at
        _id
      }
    }
  }
`

export default IndexPage

Now any docs created on Cosmic JS, will appear here on the home page!

Notice the exported query at the bottom of the file.  It contains two string type variable that will be present because we set the context object in our gatsby-node configuration.

With our newly created home page working, let’s create our doc view that will display content from the documentation that we post.

Creating our doc display page

Instead of adding a new file to the pages directory in Gatsby, we are going to create a templates directory and make a template page that we can configure on build, so that each time a doc is created, a new page can be created when we fetch our Docs from Cosmic JS.

Start by creating a templates directory at your project root, and then creating a docPage.js file within `templates` 

 Now add the page template complete with exported query that will fetch a singular doc from Cosmic JS:


import React from 'react'
import showdown from 'showdown'
import PropTypes from 'prop-types'
import Layout from '../components/layout.js'
import SEO from '../components/seo.js'
import { graphql, Link } from 'gatsby'
import hljs from 'highlight.js'
import 'highlight.js/styles/github.css'

const converter = new showdown.Converter({ ghCompatibleHeaderId: true })

class DocPage extends React.PureComponent {
  constructor(props) {
    super(props)
    this.state = {
      Doc: props.data.docs.object,
    }
  }

  componentDidMount() {
    hljs.initHighlighting()
  }

  componentWillUnmount() {
    hljs.initHighlighting.called = false
  }

  render() {
    let toc
    let doc
    for (const i in this.state.Doc.metafields) {
      if (this.state.Doc.metafields[i].key === 'table_of_contents') {
        toc = this.state.Doc.metafields[i].value
      }
      if (this.state.Doc.metafields[i].key === 'documentation') { 
        doc = this.state.Doc.metafields[i].value
      }
    }
    return (
      <Layout selectedDoc={this.state.Doc}>
        <SEO
          title={this.state.Doc.title}
          keywords={[`${this.state.Doctitle}`, 'gatsby', 'documentation']}
        />
        <div className="doc-container">
          <div className="toc-container">
            <div className="back-bttn">
              <i className="arrow left" />
              <Link to="/">Back To List</Link>
            </div>
            <div
              className="doc-toc"
              dangerouslySetInnerHTML={{ __html: converter.makeHtml(toc) }}
            />
          </div>
          <div
            className="doc-main"
            dangerouslySetInnerHTML={{ __html: converter.makeHtml(doc) }}
          />
        </div>
      </Layout>
    )
  }
}

export const query = graphql`
  query($cosmicBucket: String!, $title: String!, $readKey: String!) {
    docs {
      object(bucket_slug: $cosmicBucket, slug: $title, read_key: $readKey) {
        title
        content
        created_at
        _id
        metafields {
          key
          value
        }
      }
    }
  }
`

DocPage.propTypes = {
  data: PropTypes.object.isRequired,
}

export default DocPage

Nothing will happen with this template until we tell Gatsby that it needs to create a page using this template. We do this so that Gatsby has a chance to fetch our Documentation from Cosmic JS before it builds the page using the necessary parameters for each GraphQL query at the bottom of docPage.js.  We are using static site files after all.

Update Gatsby Node to build template pages

Let’s go ahead and add an export function to gatsby-node.js so that we are building docPage template from our GraphQL data:


require("dotenv").config();
const path = require('path');
/**
 * Implement Gatsby's Node APIs in this file.
 *
 * See: https://www.gatsbyjs.org/docs/node-apis/
 */

exports.onCreatePage = ({ page, actions }) => {
  const { createPage, deletePage } = actions

  deletePage(page)
  createPage({
    ...page,
    context: {
      writeKey: `${process.env.COSMIC_WRITE_KEY}`,
      readKey: `${process.env.COSMIC_READ_KEY}`,
      cosmicBucket: `${process.env.COSMIC_BUCKET}`
    }
  })
}

// Gatsby's built in createPages API lets you
//  explicitly create a page route from a template
exports.createPages = ({ graphql, actions }) => {
  const { createPage, createRedirect } = actions

  // configures our route and redirect slug
  createRedirect({
    fromPath: `/doc/*`,
    isPermanent: true,
    redirectInBrowser: true,
    toPath: `/`,
  })

  // This promise makes a graphql request and builds
  //  a page using the returned data and our docTemplate
  return new Promise((resolve, reject) => {
    const docTemplate = path.resolve(`src/templates/docPage.js`)

    resolve(
      graphql(`
        query {
          docs {
            objectsByType(bucket_slug: "${process.env.COSMIC_BUCKET}", type_slug: "docs", read_key: "${process.env.COSMIC_READ_KEY}") {
              title
            }
          }
        }
      `
      ).then(result => {
        if (result.errors) {
          reject(result.errors)
        }
        result.data.docs.objectsByType.forEach(doc => {
          let slug = doc.title.toLowerCase().replace(/\s/g, '-')
          createPage({
            path: `/doc/${slug}`,
            component: docTemplate,
            context: {
              cosmicBucket: `${process.env.COSMIC_BUCKET}`,
              readKey: `${process.env.COSMIC_READ_KEY}`,
              title: slug,
            }
          })
        })
      })
    )
  })
}

Now when Gatsby creates its pages, ie – the index page will fetch our docs. Create page for each doc that is retrieve, and attaching all the necessary params to the page.  So our template component is render and our GraphQL query will succeed!

3.0 Deployment

Lastly we can talk about deployment and about how static sites work.  Deploying this bad boy can be a little tricky as this site uses a static build. It won’t have the necessary pages of newly created docs until the deployment service has a chance to rebuild.

My recommendation is to use netlify and link your source from GitHub or wherever you store your code.  From there you can trigger buildhooks in order to rebuild your site whenever certain events happen.  Cosmic JS allows a post request to be fired off at endpoint when objects are created, deleted, edited, etc.  So you can easily link the two together to make some magic happen.  Keep in mind, if you want to allow users to create Docs from within your UI. We will fire a POST request manually to activate a buildhook when a doc is successfully created.

Anyway, that’s all for me folks! Happy hacking.

Categories
React Native Developers React Native Web

Deep Diving into React Native Tutorial for Beginners

Introduction

When React Native was announced, the first reactions were overwhelmingly positive. Traditionally, when we think about web technologies in the mobile space, things like Apache Cordova spring to mind, which allow us to package websites or web applications as applications for mobile platforms. In this beginners’ tutorial, we will take a look at React Native’s architecture, the philosophy behind React Native, and how it differs from other solutions in the same space. By the end of the article, we will have transformed a React “Hello World” application into a React Native one.

Let us start by saying that React Native is a relatively new technology. It has been officially available since March 2015, having been in private beta since the start of that year, and internally used at Facebook for a while before that. The saying “Rome wasn’t built in a day” generally applies to technology as well. Tools like grunt and platforms like Node.js took years to mature. In the web world, things are moving quickly, and with a huge number of frameworks, packages, and tools coming out every day, developers tend to get a little more skeptical and don’t want to jump on every hype bandwagon only to realize that they ended up in a vendor lock-in situation. We will get into what makes React Native special, why it is a technology worth getting into, and cover a few instances where it’s not all unicorns and rainbows.

Under the Hood

When talking about web technologies on mobile, available solutions usually fall in one of the following categories.

Bundling Web Applications in a Mobile Web Browser

The web application lives in a mobile browser, typically called a WebView. Without any major refactoring, a website or web application works on the mobile device. We may need to consider mobile browser events such as tapping or listening to device orientation changes and the smaller screen for a complete user experience, but we have a working mobile version with minimal effort. Cordova/PhoneGap is the most popular option in this category. Unfortunately this option has a big downside: in some cases, applications developed using Cordova are significantly slower than native applications, especially for graphical-heavy applications. In other cases, the mobile operating system doesn’t actually provide all the features in the WebView that are available in the mobile browser. The user experience can also differ from native applications; this may happen due to the application or the platform itself. This problem may range from scrollbars not feeling the same to having a noticeable delay when tapping on elements.

Compiling to Native Technologies

A completely different solution is to create a native codebase in the end. This happens by transforming the original source code into another programming language. We trade in native performance for an abstraction layer with some uncertainties. In cases of closed-source solutions, we are not even sure what happens under the hood and with what kind of black box we are dealing with. In other cases we are not sure how much the next mobile operating system update will break our code and when fixes or updates will be available. A popular example of this category would be Haxe.

Using a JavaScript Layer

Here, we use the JavaScript engine of the mobile environment and execute our JavaScript there. Native controls are mapped to JavaScript objects and functions, so when we were to call a function called fancyButtonRightHere(), a button would appear on the screen. NativeScript or Appcelerator Titanium are well-known examples of this category.

React Native could be classified as something from the third category. For the iOS and Android versions, React Native uses JavaScriptCore under the hood, which is the default JavaScript engine on iOS. JavaScriptCore is also the JavaScript engine in Apple’s Safari browsers. OS X and IOS Developers can actually directly interface with it if they want to.

One big difference is that React Native runs the JavaScript code in a separate thread, so the user interface does not block and animations should be silky and smooth.

React Is the Key Feature

It is worth noting that the “React” in React Native is not put there by accident. For React Native, we need an understanding of what exactly React offers. The following concepts work the same in both React and React Native, although these code examples are tailored to be run in the browser.

Single Rendering Entry Point

When we take a look at a simple React component, the first thing we may notice is that the component has a render function. In fact, React throws an error if there is no render function defined inside the component.

var MyComponent = function() {
  this.render = function() {
    // Render something here
  };
};

The special thing is that we don’t mess with DOM elements here, but we return an XML-based construct that represents what will be rendered in the DOM. This XML-based construct is called JSX.

var MyComponent = function() {
  this.render = function() {
    return <div className="my-component">Hello there</div>;
  };
};

A special JSX transformer takes all of that XML-looking code and converts it into functions. This is what the component after the transformation will look like:

var MyComponent = function() {
  this.render = function() {
     return React.createElement("div", {
       className: "my-component"
     }, "Hello there");
  };
};

The biggest advantage is that by taking a quick look at the component, we always know what it’s supposed to do. For example a <FriendList /> component might render a number of <Friend /> components. We can’t render our components anywhere else than inside the render function, so there is never the concern that we don’t know where exactly our rendered component came from.

Unidirectional Data Flow

To build the content of a component, React provides properties or props for short. Similar to XML attributes, we pass in the props directly to a component and can then use the props inside the constructed component.

var Hello = function(props) {
  this.render = function() {
    return <div className="my-component">Hello {props.name}</div>;
  };
};

var Greeter = function() {
  this.render = function() {
    return <Hello name="there" />
  }
};

This leads to our components being in a tree-like structure, and we are only allowed to pass data when constructing child elements.

Re-Render on Changes

In addition to props, components can also have an internal state. The most prominent example of that behavior would be a click counter that updates its value when a button is pressed. The number of clicks itself would be saved in the state.

Each of the prop and state change triggers a complete re-render of the component.

Virtual DOM

Now when everything is re-rendered when the props or state changes, how come React itself is performing that well? The magic ingredient is the “Virtual DOM.” Whenever something is needed to be re-rendered, a virtual representation of the updated DOM is generated. The Virtual DOM consists of light representations of elements modeled after the component tree, making the process of generating them much more efficient than generating real DOM elements. Before applying the changes to the real DOM, checks are done to determine where exactly in the component tree the changes happened, a diff is created, and only those specific changes are applied.

Getting Started with this React Native Tutorial

There are certain prerequisites that beginners will need to set up in order to develop for React Native. Since iOS was the first platform supported, and the one we’re covering in this tutorial, we need macOS and Xcode, at least version 6.3. Node.js is also needed. What helps is installing Watchman through the Brew package manager with brew install watchman. While this is not necessarily needed, it helps when dealing with a lot of files inside our React Native project.

React Native: The Sanest Mobile Application Development Framework.

To install React Native, we simply need to install the React Native command-line application with npm install -g react-native-cli. Calling the react-native command then helps us create a new React Native application. Running react-native init HelloWorld creates a folder called HelloWorld in which the boilerplate code can be found.

Transforming a React Application

With React being the key feature and the core principles coming from the React library, let’s take a look at what we need to transform a minimal React “Hello World” application into a React Native one.

We use some ES2015 features in this code example, specifically classes. It is completely feasible to stick with React.createClass or use a function form similar to the popular module pattern.

Step 1: Embrace CommonJS Modules

In the first step we need to change requiring the React module to use react-native instead.

var React = require('react-native');

class HelloThere extends React.Component {
  clickMe() {
    alert('Hi!');
  }
  render() {
    return (
      <div className="box" onClick={this.clickMe.bind(this)}>Hello {this.props.name}. Please click me.</div>
    );
  }
}

React.render(<HelloThere name="Component" />, document.getElementById('content'));

What is usually a part of the tooling pipeline when developing a React web application is an integral part of React Native.

Step 2: There Is No DOM

Not surprisingly, there is no DOM on mobile. Where we previously used <div />, we need to use <View />and where we used <span />, the component we need here is <Text />.

import React from ‘react';
import {View, Text, Alert} from ‘react-native';

class HelloThere extends React.Component {
  clickMe() {
    Alert.alert(‘hi!');
  }
  render() {
    return (
      <View className="box" onClick={this.clickMe.bind(this)}>Hello {this.props.name}. Please click me.</View>
    );
  }
}

React.render(<HelloThere name="Component" />, document.getElementById('content'));

While it’s quite convenient to put text directly in <div /> elements, in the native world text can’t be put directly in a <View />. For that we need to insert a <Text /> component.

import React from ‘react';
import {View, Text, Alert} from ‘react-native';

class HelloThere extends React.Component {
  clickMe() {
    Alert.alert(‘hi!');
  }
  render() {
    return (
      <View className="box" onClick={this.clickMe.bind(this)}>
        <Text>Hello {this.props.name}. Please click me.</Text>
      </View>
    );
  }
}

React.render(<HelloThere name="Component" />, document.getElementById('content'));

Step 3: Inline Styles Are the Way to Go

React Native allows us to use the Flexbox modeling instead of messing around with float and inline-block that we are so familiar with in the web world. The interesting thing is that React Native does not use CSS.

import React from ‘react';
import {View, Text, StyleSheet, Alert} from ‘react-native';

class HelloThere extends React.Component {
  clickMe() {
    Alert.alert(‘hi!');
  }
  render() {
    return (
      <View style={styles.box} onClick={this.clickMe.bind(this)}>
        <Text>Hello {this.props.name}. Please click me.</Text>
      </View>
    );
  }
}

var styles = StyleSheet.create({
  box: {
    borderColor: 'red',
    backgroundColor: '#fff',
    borderWidth: 1,
    padding: 10,
    width: 100,
    height: 100
  }
});

React.render(<HelloThere name="Component" />, document.getElementById('content'));

Using inline styles seems bewildering to beginners. It is similar to the transition React developers had to go through when being confronted with JSX and previously using templating engines like Handlebars or Jade.

The idea is that we don’t have stylesheets globally in the way we use CSS. We declare the stylesheets directly at component level, and so we have all the information we need to see what our component does, the layout it creates, and the styles it applies.

import React from ‘react';
import {Text} from ‘react-native';

var Headline = function(props) {
  this.render = () => <Text style={headlineStyle.text}>{props.caption}</Text>;
};

var headlineStyles = StyleSheet.create({
  text: {
    fontSize: 32,
    fontWeight: 'bold'
  }
});

module.exports = Headline;

Step 4: Handling Events

The equivalent to clicking in web pages is tapping an element on the mobile device. Let’s change our code so that the “alert” pops up when we tap the element.

import React from ‘react';
import {View, Text, StyleSheet, TouchableOpacity, Alert} from ‘react-native';

class HelloThere extends React.Component {
  clickMe() {
    Alert.alert("Hi!")
  }
  render() {
    return (
      <TouchableOpacity onPress={this.clickMe()}>
        <View style={styles.box}>
          <Text>Hello {this.props.name}. Please click me.</Text>
        </View>
      </TouchableOpacity>
    );
  }
}

var styles = StyleSheet.create({
  box: {
    borderColor: 'red',
    backgroundColor: '#fff',
    borderWidth: 1,
    padding: 10,
    width: 100,
    height: 100
  }
});

React.render(<HelloThere name="Component" />, document.getElementById('content'));

Instead of events being directly available on <View /> components, we need to explicitly use elements that trigger events, in our case a touch event when pressing the view. There are different types of touchable components available, each of them providing a different visual feedback.

Step 5: Customize Behavior Across Platforms

It is possible to detect which platform the React Native application is running on, by accessing the value of Platform.OS. Let’s say that, in the example above, we wanted to display a different alert message based on the platform we are running on. We can do it like this:

...
clickMe() {
  var message = ‘';
  if(Platform.OS == ‘ios') {
    message = ‘Welcome to iOS!';
  } else if(Platform.OS == ‘android') {
    message = ‘Welcome to Android!';
  }   
  Alert.alert(message);
}
...

Alternatively, the select method is also available, which provides a switch-like syntax:

…
clickMe() {
  Alert.alert(Platform.select({
    ios: ‘Welcome to iOS!',
    android: ‘Welcome to Android!'
  })
  );
}
...

In order to add a custom font, we need to jump through some hoops. First of all, make sure that the font full name and the font’s file name are the same: iOS will use the font’s full name in order to pick the font up, while Android uses the file name.

So, if your font’s full name is myCustomFont, make sure the font’s file name is myCustomFont.ttf.

After that, we need to create an assets folder and point npm to it. We can do it by creating the folder first, under assets/fonts in the application’s root directory. Any other directory will do, but this is the conventional name used for the fonts directory.

We can tell npm where we have our assets by adding an Assets property under React’s npm integration section, rnpm:

"rnpm": {
  "Assets": [
    "./assets/fonts/"
  ]
}

After we’ve done all that, we can finally run react-native link. That will copy the fonts to the right directories and will add the necessary xml to info.plist on iOS.

Once done, we can use our font by just referencing it in any stylesheet by its full name. Let’s use it on our Text element:

import React from ‘react';
import {View, Text, StyleSheet, TouchableOpacity, Alert} from ‘react-native';

class HelloThere extends React.Component {
  clickMe() {
    Alert.alert("Hi!")
  }
  render() {
    return (
      <TouchableOpacity onPress={this.clickMe()}>
        <View style={styles.box}>
          <Text style={styles.message}>Hello {this.props.name}. Please click me.</Text>
        </View>
      </TouchableOpacity>
    );
  }
}

var styles = StyleSheet.create({
  box: {
    borderColor: 'red',
    backgroundColor: '#fff',
    borderWidth: 1,
    padding: 10,
    width: 100,
    height: 100
  },
  message: {
    fontFamily: 'myCustomFont'
  }
});

React.render(<HelloThere name="Component" />, document.getElementById('content'));

Step 7: Moving Things Around

React Native uses the same rules as Flexbox for laying out components. Say we wanted to position our button at the bottom of the screen: let’s wrap our TouchableOpacity with a container View:

<View style={styles.container}>
    <TouchableOpacity onPress={this.clickMe.bind(this)}>
        <View style={styles.box}>
            <Text style={styles.message}>Hello {this.props.name}. Please click me.</Text>
        </View>
    </TouchableOpacity>
</View>

And now let’s define the container style, together with the other already defined styles:

container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center'
  }

Let’s focus on justifyContent and alignItems. Those two properties control how the component is aligned respectively along its primary axis and its secondary axis. By default, the primary axis is the vertical one, and the secondary axis is the horizontal axis (you can change that by setting the flexDirection property to row).

justifyContent has six possible values it can be set to:

  • flex-start will position all the elements together, at the beginning of the component’s bounding box.
  • flex-end will position all the elements at the end.
  • center will position all the elements in the center of the bounding box.
  • space-around will spread the components evenly, and will center the components in their created bounding boxes.
  • space-evenly will spread the components evenly as well, but it will try to leave an equal amount of space between the components and the other boundaries.
  • space-between will spread the components by keeping the spacing between adjacent components equal.

alignItems can be set to four possible values: flex-startflex-endcenter, and stretch. The first three behave like they do for justifyContent, while stretch will set the component to occupy all the available space along the axis, so that the axis will be completely filled.

So, since we want our TouchableOpacity to be displayed at the bottom and centered along the horizontal axis, we can change the style like so:

container: {
  flex: 1,
  justifyContent: 'flex-end',
  alignItems: 'center'
}

More information about the values justifyContent and alignItems can have can be found here and here.

Step 8: Registering the Application

When developing with React for the browser, we just need to define a mount point, call React.render, and let React do its magic. In React Native, this is a little bit different.

import React from ‘react';
import {View, Text, StyleSheet, TouchableOpacity, Alert, Platform} from ‘react-native';

class HelloThere extends React.Component {
  clickMe() {
    Alert.alert(Platform.select({
      ios: ‘Welcome to iOS!',
      android: ‘Welcome to Android!'
    }));
  }

  render() {
    return (
      <View style={styles.container}>
        <TouchableOpacity onPress={this.clickMe.bind(this)}>
          <View style={styles.box}>
            <Text style={styles.message}>Hello {this.props.name}. Please click me.</Text>
          </View>
        </TouchableOpacity>
      </View>
    );
  }
}

var styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'flex-start',
    alignItems: 'center'
  },
  box: {
    borderColor: 'red',
    backgroundColor: '#fff',
    borderWidth: 1,
    padding: 10,
    width: 100,
    height: 100
  },
  message: {
    fontFamily: 'myCustomFont'
  }
});

var MainComponent = function() {
  this.render = function() {
    return <HelloThere name="Component" />;
  }
};

AppRegistry.registerComponent('MainComponent', function() {
  return MainComponent;
});

We have to register the component for the Objective-C side of things, which is done using the AppRegistryobject. The name we give has to match with the name inside the Xcode project.

Our Hello World React Native application has significantly more lines of code than its web counterpart, but on the other hand, React Native takes separation of concerns a bit further, especially because styles are defined with the component.

As a side note, we shouldn’t rebind the clickMe method to the this context in the render method, especially if our React (Native) application grows to be a bit more complex. It rebinds the method on every render call which can become quite a lot. The alternative is to bind the method inside the constructor.

Running the Application

To run the application, we need to replace the contents of the index.ios.js file with the piece of code of our transformed application from the last step. Then we just need to open the Xcode project and press the big Run button. First, a terminal will open with the React Native server, and then the simulator window will appear. The React Native server creates a bundle, which the native application will then fetch. This allows for a web development-like rapid development cycle, where changes will be reflected almost instantly in the simulator.

For Android, it’s enough to add the following to your package.json file, under scripts:

"android-linux": "react-native bundle --platform android --dev false --entry-file index.ios.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/
main/res && react-native run-android"

And then run npm run android-linux. Make sure the android/app/src/main/assets directory exists beforehand.

Working with React Native

Another thing worth mentioning is that we not only use React concepts and JavaScript for our mobile applications, but some of workflows web developers are used to are also available with React Native. When coming from web development, we are used to developer tools, inspecting elements, and live reloading.

The way React Native works is that it puts all of our JavaScript files in a bundle. This bundle is either served from a server or bundled together with the application. The first is incredibly useful for development in the Simulator, as we can enable live reloading. The developer menu React provides is by no means as mighty as the Chrome Developer Tools, but it provides a very web-like developer experience with live reloading and debugging with the Chrome (or Safari) developer/debugger tools.

Web developers are familiar with JSFiddle or JSBin, an online playground for quick web tests. There is a similar environment that allows us to try out React Native in a web browser.

Categories
Development Resume Top Coder

How To Install Nginx on Ubuntu 16.04

Prerequisites

Before you begin this guide, you should have a regular, non-root user with sudo privileges configured on your server. When you have an account available, log in as your non-root user to begin.

Step 1: Install Nginx

Nginx is available in Ubuntu’s default repositories, so the installation is rather straight forward.

Since this is our first interaction with the apt packaging system in this session, we will update our local package index so that we have access to the most recent package listings. Afterwards, we can install nginx

sudo apt-get update
sudo apt-get install nginx

After accepting the procedure, apt-get will install Nginx and any required dependencies to your server.

Step 2: Adjust the Firewall

Before we can test Nginx, we need to reconfigure our firewall software to allow access to the service. Nginx registers itself as a service with ufw, our firewall, upon installation. This makes it rather easy to allow Nginx access.

We can list the applications configurations that ufw knows how to work with by typing:

sudo ufw app list

You should get a listing of the application profiles:

Available applications:
  Nginx Full
  Nginx HTTP
  Nginx HTTPS
  OpenSSH

As you can see, there are three profiles available for Nginx:

  • First, Nginx Full: This allows both port 80 (normal, unencrypted web traffic) and port 443 (TLS/SSL encrypted traffic)
  • Second, Nginx HTTP: This allows only port 80 (normal, unencrypted web traffic)
  • Third, Nginx HTTPS: This allows only port 443 (TLS/SSL encrypted traffic)

It is recommended that you enable the most restrictive profile that will still allow the traffic you’ve configured. Since we haven’t configured SSL for our server yet, in this guide, we will only need to allow traffic on port 80.

Enable this by typing:

sudo ufw allow 'Nginx HTTP'

Verify the change by typing:

sudo ufw status

HTTP traffic allowed in the displayed output:

Output
 Status: active
 To                         Action      From
 --                         ------      ----
 OpenSSH                    ALLOW       Anywhere                  
 Nginx HTTP                 ALLOW       Anywhere                  
 OpenSSH (v6)               ALLOW       Anywhere (v6)             
 Nginx HTTP (v6)            ALLOW       Anywhere (v6)

Step 3: Check your Web Server

At the end of the installation process, Ubuntu 16.04 starts Nginx. The web server should already be up and running.

We can check with the systemd init system to make sure the service is running by typing:

systemctl status nginx
Output
 ● nginx.service - A high performance web server and a reverse proxy server
    Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
    Active: active (running) since Mon 2016-04-18 16:14:00 EDT; 4min 2s ago
  Main PID: 12857 (nginx)
    CGroup: /system.slice/nginx.service
            ├─12857 nginx: master process /usr/sbin/nginx -g daemon on; master_process on
            └─12858 nginx: worker process

As you can see above, the service appears to have started successfully. However, the best way to test this is to actually request a page from Nginx.

You can access the default Nginx landing page to confirm that the software is running properly. You can access this through your server’s domain name or IP address.

If you do not want to set up a domain name for your server, you can use your server’s public IP address. If you do not know your server’s IP address, you can get it a few different ways from the command line.

Try typing this at your server’s command prompt:

ip addr show eth0 | grep inet | awk '{ print $2; }' | sed 's/\/.*$//'

You will get back a few lines. You can try each in your web browser to see if they work.

An alternative is typing this, which should give you your public IP address as seen from another location on the internet:

sudo apt-get install curl
curl -4 icanhazip.com

When you have your server’s IP address or domain, enter it into your browser’s address bar:

http://server_domain_or_IP

You should see the default Nginx landing page, which should look something like this:

This page is simply included with Nginx to show you that the server is running correctly.

Step 4: Manage the Nginx Process

Now that you have your web server up and running, we can go over some basic management commands.

To start|stop|restart|reload|disable|enable your web server, you can type:

sudo systemctl stop nginx
sudo systemctl start nginx
sudo systemctl restart nginx
sudo systemctl reload nginx
sudo systemctl disable nginx
sudo systemctl enable nginx

Step 5: Get Familiar with Important Nginx Files and Directories

Now that you know how to manage the service itself, you should take a few minutes to familiarize yourself with a few important directories and files.

Content

  • /var/www/html: The actual web content, which by default only consists of the default Nginx page you saw earlier, is served out of the /var/www/html directory. This can be changed by altering Nginx configuration files.

Server Configuration

  • /etc/nginx: The Nginx configuration directory. All of the Nginx configuration files reside here.
  • /etc/nginx/nginx.conf: The main Nginx configuration file. This can be modified to make changes to the Nginx global configuration.
  • /etc/nginx/sites-available/: The directory where per-site “server blocks” can be stored. Nginx will not use the configuration files found in this directory unless they are linked to the sites-enabled directory (see below). Typically, all server block configuration is done in this directory and then enabled by linking to the other directory.
  • /etc/nginx/sites-enabled: The directory where enabled per-site “server blocks” are stored. Typically, these are created by linking to configuration files found in the sites-availabledirectory.
  • /etc/nginx/snippets: This directory contains configuration fragments that can be included elsewhere in the Nginx configuration. Potentially repeatable configuration segments are good candidates for refactoring into snippets.

Server Logs

  • /var/log/nginx/access.log: Every request to your web server is recorded in this log file unless Nginx is configured to do otherwise.
  • /var/log/nginx/error.log: Any Nginx errors will be recorded in this log.

Conclusion

Now that you have your web server installed, you have many options for the type of content to serve and the technologies you want to use to create a richer experience.

Categories
Top Coder

Understanding Evolutionary Computation for AI

Some time ago, I began work on a program to make movies. An editing program? Well, no. In fact, it was program that was asked to make a presentation when given a topic.

For instance, it might be given the name of city or a diet plan. The program would then search the internet for pictures to put into a small movie or presentation. The program thought about the kind of presentation it needed to make for the topic, e.g. a book, flowing with music, or other things. It did a pretty good job making very simple presentations in its infancy.

And, what was its secret? Well it organized media into groups, each targeted for some place in a presentation. So, for example, several pictures could be made into candidates for a place in the presentation. And, more candidates might have been created as well by changing the existing candidates. The media could also be presentations as well — presentations within presentations.

The program made various versions of the presentation (not too many), and eventually figured out which presentation and media might be best for the topic. Further info can be found in a patent by Schoenbach and Leddy 2010.

The secret was about those candidates. The program gathered together candidates, a small population, and made changes to the candidates to get more on each cycle of the program.

Some might call the changes mutations. Some might call the cycles of the program at the time of a new generation. And, you might recognize some of this lingo as belonging to discussions about evolution of species.

Perhaps it’s a blast from your biological past like something from a high school biology course. We recall from high school biology that species evolve to fit their environment. The best fit are those who can sustain on the resources and stay around long enough to produce offspring. Environments can include a number of features such as the kind of food and water available, the exposure to the sun, the amount of air or the kind of air, etc.