About the Author:

A Primer on ES2017 Async and Await

February 11th, 2017

As the year 2016 draws to a close, attention is now turning to what will emerge from 2017, with Javascript as much as anything. The language is undergoing a massive evolution now, increasingly taking on characteristics that make it attractive as a full stack environment.

The ES2017 (ES8) stack is already now being implemented in both Node and several modern browsers, addressing many of the more complex issues of web development including better ways of dealing with asynchronous coding. This piece will give a short primer on working with the new ES2017 features Async and Await.

Async and Await

More than almost any other language, JavaScript has struggled with a seemingly simple problem – how do you keep interfaces responsive when you have to fetch (or send) contents over a data socket across the web? The first solution to that was to write polling routines to activate a setTimeout or setInterval call, then returning a flag state that indicated a given transfer was complete. With the advent of AJAX calls in the late 1990s, this functionality was relegated to a specific object, the XmlHttpRequest object, and later eventually subsumed in jQuery oriented ajax(), get() and post() functions.

This, in turn, introduced the notion of asynchronous callbacks into Javascript – passing a function as an argument to another asynchronous function with a predetermined set of parameters. Such callback functions would then be invoked once either the data had completed transferring or an error had occurred (in which cases a different function would be passed for cleaning up the action).

One problem became quickly evident with this approach. The resulting callback functions themselves often needed to push the resuting data to another function, which would require another callback, and eventually the resulting code became hideously deep and complex.

The first solution to this problem was to implement a construct called a promise. A promise was a deferred callback object that was implemented initially in ES2015, then refined in ES2016. A promise was a wrapper object that held the callback function(s). When the invoked asynchronous function completed, then it would return a resulting object that could then be passed into a new promise, resulting in a promise chain.

This construct was better, but could still end up being too verbose, especially when what you needed was data from multiple sources independently. The async identifier, along with the await keyword, is the ES2017 solution to that particular problem. As a simple example , first create a promise, in this case a promise of a function that returns a value after a specified number of seconds:

function resolveAfterInterval(x,t) {
 return new Promise(resolve => {
  setTimeout(() => {
   resolve(x * x);
  }, t * 1000);
 });
}

Here, the function resolveAfter interval takes two parameters, a value that will be squared, and the time in seconds. The function creates a new promise around a function (internally called resolve()) that in turn calls a setTimeout function. The resolve function is itself just a placeholder that returns whatever is passed into it, here the square of the number. The t parameter in turn is used to set the number of seconds before the function returns.

The await keyword is applied to a function or variable to indicate that it should await the completion of the promise before passing the results of that promise. If the await is passed on the variables, then the return statement is invoked once the last of the variables are known, here at three seconds.

async function distance1(x) {
 var a = resolveAfterInterval(20,2);
 var b = resolveAfterInterval(30,3);
 return Math.sqrt(Math.pow(x,2) + Math.pow(await a,2) + Math.pow(await b,2));
}
distance1(10).then((v)=>console.log(v))

Note that that await serves very much the same purpose in an asynchronous function that yield does for a generator (and they use many of the same mechanics under the hood). Here, the output will return only once the longest promise’s interval completes, at 3 seconds.

This is a little different from the situation where the awaits is applied to the functions themselves:

async function distance2(x) {
 var a = await resolveAfterInterval(20,2);
 var b = await resolveAfterInterval(30,3);
 return Math.sqrt(Math.pow(x,2) + Math.pow(a,2) + Math.pow(b,2));
}
distance2(10).then((v)=>console.log(v))

In this example, the first await won’t return until after two seconds, while the second await won’t return until three seconds after the first one is satisfied (or five seconds after the code starts). This occurs because the await acts like an asynchronous block – in the second example, the following statement won’t occur until after the initial function’s promise is returned, but in the first example, the return statement executes once the variables have been assigned.

Using await is actually quite valuable in situations where you want an action to occur once all of the data is available from all sources, but not a moment after. Ordinary chaining of promises is almost as bad as synchronous processing (since you’re dependent upon waiting for one promise to complete before a second one can start, as the second example shows), but with the async and awaits keywords you can reduce this wait only to that of the longest single process.

Summary

ES 2017 is the culmination of an upgrade cycle that has significantly changed the flavor of the Javascript language, bringing it more in line with contemporary functional languages such as Haskell or Scala. The language that has emerged is becoming quite powerful and expressive. At the same time, there is a huge amount of innovation occurring with various libraries such as mobX, React and elsewhere, and these in turn are becoming grist for strengthening the core language to better reflect these innovations.

About the Author:

Google Maps in React / Redux: Interactivity Across Different Components

January 20th, 2017

Rich UIs provide users with a variety of ways to interact. For example, HipCamp, a platform for discovering camping opportunities, uses a combination of a map-based UI and an informative list of campgrounds:

hipcamp.png

This split UI gives users an idea of location through identifying the campground on a map, while keeping the map tidy by using the marker info windows as basic identifier, keeping the more verbose content within the campground list.

Explore React Courses

In this post we will build on our previous learnings in list filtering through state management in React/Redux by adding a map to the UI. We will see how to use state to link the list and map views together, enabling the user to leverage the information of both UI elements when interacting with one or the other. We will also extend the filtering functionality to the markers by connecting the map components to the same state elements as the filter components. The resulting app will filter both the markers and the campground list, and provide users with visual cues when interacting with one or the other. Clicking on a marker will pop up an info window showing the campground name and also highlight the corresponding list item by changing the border. Likewise, clicking a list item will open the info window for the corresponding marker and change the item border:

map.png

You can get the code for this app on GitHub and interact with it live at this Heroku demo app. We will continue using the google-maps-react npm module and some of the techniques outlined on Full Stack React for working with this package. All of our state management will be done via Redux, as opposed to at the component level in the Full Stack React article.

Adding the Map

Picking up where we left off in the previous post, we will add a google maps container to CampFilterApp.jsx:

render() {

 return (

 <div className="container">

 <Jumbotron>

 <h1>
 Crater Lake Camping
 </h1>

 </Jumbotron>

 <br></br>

 <CampFilterList {...this.props }/>

 <br></br>

 <CampMapContainer {...this.props }/>

 <br></br>

 <CampList {...this.props }/>

 </div>

 )
};

The CampMapContainer component will serve as a wrapper for the google maps components, and a point of entry for the GoogleApiComponent provided by google-maps-react. First lets look at the render method for CampMapContainer.jsx:

 

render() {

 return (

 <div>

 <CampMap google={this.props.google}>

 {this.props.markers.map(marker =>

 <Marker

 key={marker.get('title') }

 title={marker.get('title') }

 description={marker.get('description') }

 properties={marker.get('properties') }

 position={marker.get('position') }

 mapOn={marker.get('mapOn') }

 addMarker={this.props.addMarker}

 onMarkerClick={this.props.onMarkerClick}/>

 ) }

 <InfoWindow {...this.props}

 marker={this.props.activeMarker}

 visible={this.props.showingInfoWindow}>

 <div>

 <h4>{this.props.selectedTitle}</h4>

 </div>

 </InfoWindow>

 <CampList {...this.props}/>

</div>

 ) }

We have four components inside the container – CampMap is a container for the map itself, which contains a marker component for each marker in our markers property and an InfoWindow component to be set based on the activeMarker property. We will discuss these components more in detail in a bit.

After the class definition in CampMapContainer.jsx, we will add an export for the google maps component:

let key = config.getGoogleKey()

export default GoogleApiComponent({

apiKey: key

})(CampMapContainer)

You can use the API key included in the config supplied with the config.js file for demonstration purposes, but please don’t abuse it! You can use the google-maps-react package without an API key, but by providing one we receive a google property which can be passed to the components to create markers, info windows, and maps as we will see shortly. Notice that the <CampMap> component in the render method above makes use of the google property.

Lets dive into the Google Maps components.

The CampMap Component

This component sets up our map and renders the Marker components. In the render method, we set the min size for the map and call the renderChildren function. You can check out that code in CampMap.jsx. Essentially, it will render any children of the map object, in our case the Marker components, passing on the google and map properties.

render() {

 const style = {

 minWidth: '400px',

 minHeight: '400px'

 }

 return (

 <div className="row">

 <div style={style} ref='map'>

 {this.renderChildren() }

 Loading map...

 </div>

 </div>

 )

}

Recall above that we passed the google property to this component. The API connection is asynchronous, meaning that initially this property will be undefined. When the API returns, the google property will be updated, resulting in a ComponentDidUpdate event on the CampMap component. This has two impacts:

  1. When the render method is initially called, and the Markers are rendered as a result, the map property passed to the Markers in renderChildren will be undefined. This means the markers will not be attached to the map since it does not yet exist. In order to attach the markers to the map we will need to renderChildren again after the API returns.
  2. We need to wait until the API returns a valid google property to load the map.

To account for this, we will handle the ComponentDidUpdate event in the CampMap component, calling both the loadMap function that draws the google map and forceUpdate, which will force the component to re-render including the call to renderChildren. We will only do this if the google property has been updated, to avoid re-rendering for other cases where componentDidUpdate is fired. The loadMap function sets the map parameters and attaches it to the DOM, see CampMap.jsx.

componentDidUpdate(prevProps, prevState) {

 if (prevProps.google !== this.props.google) {

 this.loadMap();

 this.forceUpdate()

 }

}

The Marker Component

Now that we have our map created, let’s take a look at the Marker component, which receives the google and map properties from its parent component, CampMap, in addition to these properties defined in CampMapContainer:

<Marker

key={marker.get('title')}

title={marker.get('title')}

description={marker.get('description')}

properties={marker.get('properties')}

position={marker.get('position')}

mapOn={marker.get('mapOn')}

addMarker={this.props.addMarker}

onMarkerClick={this.props.onMarkerClick}/>

Because google maps renders components directly to the DOM, the render method of this component simply returns null. Instead, we render the marker when there is a change in the map property or in the marker properties or mapOn properties. We are only looking at changes in these specific marker properties because the others are static in our application. See the ComponentDidUpdate method in Marker.jsx

You’ll notice that we are passing two actions down to the Marker component; addMarker and onMarkerClick. The addMarker action is used to create a list of google marker objects as part of the Redux state. This marker array will be used to allow interactivity between the markers and the campground list items. The onMarkerClick action will be used to set the info window content. We will discuss these actions more in detail later on. The InfoWindow component implementation is from the Full Stack React Google Maps article, which you can reference to understand the lifecycle of this component.

The CampListItem Component

We need to make a few changes to our CampListItem component from the last post to change the border of the selected element and enable opening the corresponding marker’s info window. Let’s take a look at the image in the CampListItem component render method:

<img src={img_url} alt="campground" ref="cg_image" style={{width:200, height:100}} onClick={() =>this.props.onMarkerClick(this.getMarker(this.props.title))}></img>

We’ve added a ref property to the image which we will use to set the border style when the item is selected. We’ve also added a click handler to call onMarkerClick with the current marker. This is the same onMarkerClick called by the Marker component, which will set the info window content and open/close it as required. Notice that we are calling a local function getMarker to retrieve the current marker for the onMarkerClick parameter. First let’s take a look at setting the style with the ref property in CampListItem.jsx:

componentDidUpdate(prevProps, prevState) {

if (this.props.activeMarker !== prevProps.activeMarker) {

let img_ref = this.refs.cg_image

if (this.props.showingInfoWindow && (this.props.selectedTitle === this.props.title)) {

img_ref.style.border = "3px solid black"

}

else {

img_ref.style.border = null

}

}

}

On ComponentDidUpdate we check to see if the activeMarker field has changed, and if so we proceed with changing the image border. Next, we will either add the border if this item is selected, or remove it if it is no longer selected. If it turns out that the info window should be shown and the selectedTitle property matches the title of the current marker we will update the border to “3px solid black”, otherwise we set the border to null.

Recall that we have been using addMarker to create an array of google maps markers as part of our Redux state whenever a new marker is rendered. We now have two arrays of markers as part of our state, from index.js:

function set_state(campgrounds) {

 store.dispatch({

 type: 'SET_STATE',

 state: {

...

 markers: campgrounds,

 gmapMarkers: [],

 ...

}

})

}

The markers array is our geoJSON-based markers used for filtering and displaying data. The gmapMarkers array is for the google marker objects we need for the map markers. Both sets of markers have a title field that can be used to link the two. In the CampListItem component, the marker property is from the markers array. The onMarkerClick action needs a marker from the gmapMarkers array in order to attach the info window to the correct marker, so we have a helper function getMarker that retreives the matching gmapMarkers element to provide to onMarkerClick:

getMarker(title_match) {

 let match_list = this.props.gmapMarkers.filter(item =>

 item.get('title') === title_match

 )

 if (match_list) {

 return match_list.first()

 }

 else {

 return null;

 }

}

Where this.props.title is provided as the title_match parameter.

Now that we’ve discussed the component hierarchies, let’s take a look at how to hook up these actions in Redux.

Redux Implementation

Remember we first need to add our new actions to the action_creators.js file, which you can review here. Next, we add the following to our reducer.js file to handle these new actions:

function onMarkerClick(state, marker) {

 return state.merge(Map({

 'activeMarker': marker,

 'selectedTitle': marker.get('title'),

 'showingInfoWindow': true

 }))

}

function addMarker(state, marker) {

 let markers = state.get('gmapMarkers')

 let newMarkers = markers.push(marker)

 return state.update('gmapMarkers', oldmarkers => newMarkers)

}

Whenever the markerOnClick event is fired, we want to show the info window, so showInfoWindow is set to true. activemarker and selectedTitle are set based on the marker passed up from a CampListItem or Marker component. For addMarker, we simply add the new marker to the existing gmapMarkers array. Don’t forget to add the new actions to the reducer:

export default function (state = Map(), action) {

 switch (action.type) {

 case 'SET_STATE':

 return setState(state, action.state);

 case 'CHANGE_FILTER':

 return changeFilter(state, action.filter);

 case 'MARKER_CLICK':

 return onMarkerClick(state, action.marker)

 case 'ADD_MARKER':

 return addMarker(state, action.marker)

 default:

 return state

 }

}

One last change to make in the reducer, and this is for the changeFilter action. Recall that we used a mapOn property in the Marker component:

if (!this.props.mapOn) {

 this.marker.setMap(null);

}

else {

 this.marker.setMap(map)

}

The mapOn property was added to the geoJSON-based markers array to set marker visibility based on the filter settings. Adding the following to changeFilter in reducer.js will set mapOn to true of the marker should be shown:

let markers = state.get('markers')

let updatedMarkers = markers

markers.forEach(marker => {

 let markerIndex = getMarkerIndex(state, marker.get('title'))

 let mapOn = true

 active_filters.forEach(item => {

 if (marker.get('properties').get(item.get('id')) !== true) {

 mapOn = false

 }

 })

Based on the mapOn property we can “remove” the markers not to be displayed based on the current filter settings by marker.setMap(null) if mapOn is false.

And that’s a wrap! Using the gmapMarkers property and invoking the onMarkerClick action from both the Marker and CampListItem components we have enabled opening of the InfoWindow from clicking on the CampListItem image and highlighting the CampListItem image as a result of clicking on the Marker. The additional field mapOn enables us to filter both the campground list and the markers.

About the Author:

List Filtering through State Management: Moving from jQuery to React/Redux

January 6th, 2017

Most web applications give people an interface to interact with and explore data. Thus, a core challenge of building applications is continuously and reliably syncing the data with the user interface. Toggled switches should stay toggled. Checked boxes should stay checked. Pushing the ‘like’ button should change that button to ‘liked’. The right data should be showing at the right time. This all fits into the realm of managing ‘state’.

In simple apps, vanilla JavaScript or jQuery generally work fine for managing state. But as applications grow in size and complexity, JS/jQuery can turn into spaghetti code. It will become much harder to know which code is affecting which part of the state. This can create bugs for users and suffering for the developers who have to fix those bugs.

JavaScript libraries and frameworks have been evolving quickly to make applications more reliable and easy to debug. This state management problem is getting easier. React and Redux are two libraries (often used together) that have gained a lot of use in the last 2 years. This tutorial will cover the process of converting a jQuery app to React/Redux.

Explore React Courses

In our prior post about using JQuery and Google Maps to display and filter campgrounds, we learned how to leverage GeoJSON properties to control which markers are displayed on the map, allowing us to see only a subset of campgrounds that meet our criteria.

screen-shot-2017-01-06-at-5-24-00-pm

While this is a fine way to design front end filtering, we can improve upon it using React and Redux to help us make our implementation more DRY than WET. In this post we will learn how to build a campground filtering interface using React/Redux by exploring how this architecture can improve on our prior JQuery implementation. Here are some benefits of making the switch:

  • To add a new filter option in our JQuery implementation, we would have to manually add a new filter button to the UI and hook up event handlers. With React/Redux, we can define the filters we want at runtime and let React/Redux handle the UI and event updates for us.
  • By using state we can avoid having to query the DOM or maintain global variables to keep track of what filters are currently in use
  • React will only redraw elements of the UI which have been altered by changes in state, resulting in faster rendering.
  • Using React components, we can compartmentalize different parts of the UI into separate classes, enabling us to easily update and add new components without having to touch the entire codebase.

In this post we will learn how to create the filtering used in this demo app for finding campgrounds near Crater Lake using React, Redux, and react-bootstrap (for simple styling). You can see the complete code on Github.

screen-shot-2017-01-06-at-5-25-20-pm

The React Components

Lets get started by going over the React components we will use to filter campgrounds. Our top level component, CampFilterList, will create items of type CampFilter from a list of filters passed down via props. Taking a look at CampFilterList.jsx:

render() {

   return (

     <div className="row">

       <div className="col-sm-4">Campground Filters:</div>

       {this.props.filters.map(item =>

         <CampFilter id={item.get('id')}

                 key={item.get('id')}

                 changeFilter={this.props.changeFilter}

                 />

       )}

     </div>

 )}

For each item in the filters list we create a CampFilter component with the id that will be passed back to the changeFilter method, which we will discuss in the Redux section. Taking a look at the CampFilter component, we can see how the changeFilter method is called on click, and the id sent as its parameter.

render() {

return (

<div className="col-sm-2">

<input type="checkbox"

className="toggle"

id={this.props.id}

defaultChecked={this.props.inuse}

onClick={() => this.props.changeFilter(this.props.id)}/>

&nbsp;

<label ref="text">{this.props.id}</label>

</div>

)

}

When a filter is checked, the changeFilter method is called back through the store to the reducer, changing the inuse field, resulting in the campgrounds list being filtered. Like the filters the campgrounds components are list/item, but don’t have any user interaction. You can check out the details in CampList.jsx and CampListItem.jsx.

Setting up the Redux store

Now that we have our filtering React components, let’s go over how we will use Redux to manage state and do the campground filtering.

First, we need to define the initial state for our app in index.js:

function set_state(markers) {

store.dispatch ({

type: 'SET_STATE',

state: {

filters: [

{id: 'shower', inuse: false },

{id: 'pets', inuse: false },

{id: 'flush', inuse: false },

{id: 'water', inuse: false }

],

campgrounds: campground_list

}

})

}

In the set_state function we define a list of filters to be used for our app.  The “inuse” field will keep track of how the user is filtering items in the UI. We also define a list of campgrounds that we will apply the filters to. The campgrounds are read from a geoJSON file with properties relating back to the filters:

"type": "Feature",

"geometry": {

"type": "Point",

"coordinates": [-122.166149, 42.865508]

},

"properties": {

"flush": true,

"shower": true,

"pets": true,

"water": true,

"description": "Flush toilet, Shower",

"title": "Mazama",

"image": "mazama.jpg",

"url": "https://www.craterlakelodges.com/lodging/mazama-village-campground/",

"marker-size": "small"

You can see how the properties map back to the filter IDs, for example, the ‘pets’ property in the geoJSON corresponds to the filter with ID ‘pets’.

The store variable in the set_state function refers to the Redux store, which will handle the state updates for our app. To create a Redux store we need to have a reducer to handle state transition. Let’s add the SET_STATE action to the reducer in reducer.js, enabling us to execute the above code:

export default function(state = Map(), action) {

switch (action.type) {

case 'SET_STATE':

return setState(state, action.state);

default:

return state

}

}

We are using the immutable.js library, so in the setState function we can simply merge the new state with the old without having to add additional code to avoid mutating the state when updating.

function setState(state, newState) {

return state.merge(newState);

}

We will also need a method for updating the filters based on the user’s interactions, so let’s add that to the reducer as well:

export default function(state = Map(), action) {

switch (action.type) {

...

case 'CHANGE_FILTER':

return changeFilter(state, action.filter);

...

The CHANGE_FILTER action will occur when a checkbox is clicked, so our changeFilter implementation should 1. Identify which member of the filter list initiated the CHANGE_FILTER action and 2. Toggle the value of that member’s inuse property and 3. Return the updated filter values as part of the new state:

function getFilterIndex(state, itemId) {

return state.get('filters').findIndex(

(item) => item.get('id') === itemId

);

}

function changeFilter(state, filter) {

let filterIndex = getFilterIndex(state,filter)

const updatedFilter = state.get('filters')

.get(filterIndex)

.update('inuse', inuse => inuse === false ? true : false);

return state.update('filters', filters => filters.set(filterIndex, updatedFilter));

}

With the SET_STATE and CHANGE_FILTER actions described in the reducer, we can now create the store used to dispatch our initial SET_STATE command to in index.js:

import reducer from './reducer'

const store = createStore(reducer)

set_state(get_campgrounds(features))

Where get_campgrounds is the function that converts the geoJSON features to a list of objects for the campgrounds state element referenced in the set_state function.

We can now render our app, passing the Redux store as the Provider for the app. This enables the app to interact with the Redux dispatcher to process state changes:

ReactDOM.render(

<Provider store={store}>

<CampFilterAppContainer />

</Provider>,

document.getElementById('root')

);

With the Redux dispatcher set up, we can now move on to creating the app container, where we will map the actions for our app back to the dispatcher and set the props to be used by the app.

The action_creators.js file is our link between the delegate props that will be sent to the children components and the Redux store. In action_creators.js we define a function to handle filter changes:

export function changeFilter(filter) {

return {

type: 'CHANGE_FILTER',

filter

}

}

The changeFilter function returns an action with parameters type and filter, which might look familiar to you looking back at reducer.js:

export default function(state = Map(), action) {

switch (action.type) {

...

case 'CHANGE_FILTER':

return changeFilter(state, action.filter);

...

In addition to the action creators, we need to map the state from the Redux provider to the props that will be passed to the React components. In addition, we will perform the filtering of the campgrounds in the app container before sending the campgrounds down to the components to get rendered. First, let’s get the active filters, those with inuse true, so we know how to filter the campgrounds. From CampFilterApp.jsx:

function mapStateToProps(state) {

let filters = state.get('filters')

let campgrounds = state.get('campgrounds')

let filtered_campgrounds = campgrounds

let active_filters = filters.filter(

item => item.get('inuse') === true

)

...

}

Notice that we start by setting filtered_campgrounds to the entire campgrounds list. In the event that none of the filters are selected, such as when we first load the app, we want to pass all the campgrounds to the React components. Next, we iterate through all the active filters, keeping only the campgrounds that have true properties matching the active_filters:

active_filters.forEach(filter => {

filtered_campgrounds = filtered_campgrounds.filter(

item => item.get('properties').get(filter.get('id')) === true

)

})

If there are no active filters the filtered_campgrounds list remains unchanged, meaning all campgrounds will be displayed.

Finally, now that we have the list of filtered campgrounds, we return this and the other state information as props:

return {

filters: filters,

campgrounds: filtered_campgrounds

};

Phew! We are now ready to create the app container, connecting the action creators and the mapped states to the CampFilterApp component:

export const CampFilterAppContainer = connect(mapStateToProps,actionCreators)(CampFilterApp);

Recall that CampFilterAppContainer was referenced in the ReactDOM.render() function in index.js. It’s a little circuitous, so let’s just recap what we went over here:

  1. We created the Redux store based on the methods in reducer.js, which define how changes in state are handled
  2. We created an app container to
    1. stick together the action creators, which define the interface between the components and the reducer, with
    2. the redux store state, which is mapped to properties, resulting in creating the props that will be consumed by the React components.
  3. We render this app container when the app is initialized in index.js

Last but not least, we can now render the app. From CampFilterApp.jsx:

render() {

return (

<div className="container">

<Jumbotron>

<h1>Crater Lake Camping</h1>

</Jumbotron>

<br></br>

<CampFilterList {...this.props}/>

</div>

)};

The props that are being passed to the React components will include the filters and filtered_campgrounds defined in index.js (mapped to props in CampFilterApp.jsx) and the changeFilter action defined in action_creators.js.  Recall from our React components above that changeFilter is attached to the filter checkbox onClick event, so our app will now filter the campgrounds.

Give it a try using the demo app on Heroku or download the code and run it for yourself. If you want to add a new filter simply add a new field to the geoJSON features and a corresponding item to the filter state list and let React/Redux take care of the rest!

Explore React Courses

About the Author:

Using JavaScript ASync Functions

December 3rd, 2016

Async stands for asynchronous and it is (aptly) the opposite of synchronous programming. To get a better grasp on Async functions, you need to first fully understand synchronous code. Simply put, synchronous code means “many statements in a sequence”. Each statement is executed one after the other. This also means that a statement has to wait before the other one is finished.

console.log(‘1st’);
console.log(‘2nd’);
console.log(‘3rd’);

The previous code above will execute and output the “1st”, “2nd”, “3rd” strings in a row to the console. Simple. It is written synchronously.

Asynchronous code will execute statements outside of the main flow. This allows for async functions to be executed right away without having to wait. Developers see both states of code. An example of Async programming is shown with a simple jQuery function:

console.log('1st');
jQuery.get('page.html', function (data) {
    console.log("2nd");
});
console.log('3rd');

The output from the example above will be different. “1st”,”3rd”, “2nd”. This is due to the function passing through jQuery.get and not being immediately called. Instead the function has to wait for jQuery to fetch the page before executing.

Async Code: Benefits & Uses

Once the code had run, there is a chance that synchronous code can block future executions. This happens because it is waiting for prior statements to finish. Basically, this means that the UI can become unresponsive until a function has finished. This should be avoided at all costs as it can damper the user experience.

A developer named Brian Terlson, is working on implementing native Async functions into ECMAScript. Currently, it’s in proposal mode and in step three(candidate) of being implemented part of ES7.

Variants of async functions currently exist. The unique keyword is async before every declaration. Here is the following syntax:

  • Async function declarations: async function foo() {}
  • Async function expressions: const foo = async function () {};
  • Async method definitions: let obj = { async foo() {} }
  • Async arrow functions: const foo = async () => {};

Generally, you’ll want to use asynchronous code to perform expensive, time consuming operations. It wouldn’t be used for something simple like changing the CSS class of an element. Here is an example of another async function, but this time with the keyword async in front of it.

 
async function asyncFunc() {
    return xyz;
}

asyncFunc()
.then(x => console.log(x));
    // xyz

Notice the “.then” operator. An async function is passed through the argument by something called a Promise implementation. According to its definition, a promise represents “a value which may be available now, or in the future, or never.”

A promise is in three different states:

  • pending: starting state, not yet fulfilled or rejected.
  • fulfilled: the operation has finished successfully.
  • rejected: the operation has failed.

So to recap, asynchronous code should be used for when synchronous code won’t cut it. It adds a new degree of complexity that will keep your user experience smooth and flowing. Your application or website stays responsive, and reduces idle time for the end user. Native implementation of Async functions will make this a ubiquitous way to execute aysnc functions.

About the Author:

Comparing Angular 1 & Angular 2 Through Building a Pomodoro Timer

November 4th, 2016

Modern web development offers an incredible variety of tools, libraries, and frameworks to build web sites/applications. As of 2016, jQuery, React, Angular, and Vue are the most popular front-end libraries/frameworks in use. They can all be used to build and accomplish similar things, but in different ways. What are the advantages/disadvantages of each? How does each approach vary? What do the new tools of React, Vue, and Angular 2 offer that Angular 1, jQuery, and vanilla JS didn’t?

In part 1 of the series, we saw the similarities and differences between javascript and jQuery while building the same pomodoro app and we also discussed the advantages and disadvantages of each. In part 2 of the series, we will see how to use angular 1 and angular 2 to build the same pomodoro timer and we will discuss the difference in approaches taken by the two frameworks.

Explore Angular Courses

What is a pomodoro timer?

The pomodoro timer is an easy-to-use productivity method. Using this method, you work in 25 minute spurts with 5 minute breaks in between. Many people find it helpful for helping them focus and work on tasks during the day.

pomodoro timer

Project Overview

In this tutorial, first we will create a pomodoro timer using Angular 1. Then, we will re-create the same pomodoro timer using Angular 2.

Here is how the final version of pomodoro timer built using Angular 1 looks like :

See the Pen Pomodoro Timer : : Angular1.5 by Raj Gupta (@rajdgreat007) on CodePen.

Here is how the final version of pomodoro timer built using Angular 2 looks like :

See the Pen Pomodoro Timer : : Angular2 by Raj Gupta (@rajdgreat007) on CodePen.

Our pomodoro timer shows minutes, seconds, and gives simple control buttons. It’s a simple timer but can give enormous productivity gains if used right.

Building the Pomodoro Timer : Angular 1

Let’s first write the html code to create various elements of the pomodoro timer.

<div id="pomodoro-app">
<div id="container">
<div id="timer">
<div id="time">{{toDoubleDigit(minutes)}}
:
{{toDoubleDigit(seconds)}}</div>
<div id="filler"></div>
</div>
<div id="buttons"><button id="work">Work</button>
<button id="shortBreak">Short Break</button>
<button id="longBreak">Long Break</button>
<button id="stop">Stop</button></div>
</div>
</div>

Angular 1 has MVC(Model, View, Controller)/MVVM(Model, View, ViewModel) architecture. The model represents data (eg. javascript objects) of the application. The view is how we can display the data to user. Since Angular 1 supports two way data binding, any change in the model will automatically update the view and vice versa. The controller consists of the code that controls the interaction between model and view.

By setting ng-app=“pomodoroApp”, we are marking the corresponding div (with id pomodoro-app) as the root element of the Angular application. “pomodoroApp” is the name of the angular module that we will define later in javascript code. By setting ng-controller=“pomodoroController”, we are attaching a controller function (will be defined later) to the view. The controller function will consist of variables and functions needed for the view. ng-click defines the function (defined in controller) that will be executed when the corresponding button is being clicked. We will be using a background filler that will keep increasing as time progresses.

Let’s apply css to the above markup.

#container{
border:1px solid #333;
border-radius :20px;
width:400px;
margin:20px auto;
padding:20px;
text-align:center;
background : #333;
}

#timer{
color:#f00;
font-size:50px;
margin:10px auto;
border : 5px solid red;
border-radius:50%;
width:200px;
height:200px;
overflow:hidden;
position:relative;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
cursor:default;
}

#time{
margin-top:70px;
z-index : 1;
position:relative;
}

/*
filler width is set to 200px (i.e. equal to width of the timer) so that it completely covers the timer in background. The height is initially set to 0px and it increases as timer progresses to give background fill effect.
*/

#filler{
background : #ddffcc;
height: 0px;
width: 200px;
position:absolute;
bottom:0;
}

#buttons button {
background:#4da6ff;
border:none;
color:#fff;
cursor:pointer;
padding:5px;
width:90px;
margin:10px auto;
font-size:14px;
height : 50px;
border-radius : 50px;
}

#buttons button#shortBreak{
background : #0c0;
}

#buttons button#longBreak{
background : #080;
}

#buttons button#stop{
background : #f00;
}

Now, let’s make the pomodoro app functional by adding the following javascript :

var app = angular.module("pomodoroApp", []);
/* Define a module named pomodoroApp*/

/* Defind the angular component*/
app.component('pomodoroComp', {
bindings: {},
templateUrl: '/componentGrid.html',
controller : ['$interval',function(interval){

var self = this;
self.started = false;
/* 
started variable stores the state of the timer. If it is true, it means that some task (work, short break, long break) is going on with pomodoro timer. If it is false, it means that the pomodoro is not yet started or it is stopped (by clicking stop button)
*/

self.minutes = 25;
/*
minutes variable stores current minute which is displayed in the pomodoro. 
*/

self.seconds = 0;
/*
seconds variable stores current second which is displayed in the pomodoro.
*/

self.fillerIncrement = 200/(self.minutes*60);
/*
fillerIncrement variable stores the value by which fillerHeight should increase.
*/

self.fillerHeight = 0; 
/*
fillerHeight variable stores the height of the background filler. Initially it is set to 0. As soon as a pomodoro task starts, its height starts increasing (by a value which is stored in fillerIncrement variable) and it keeps increasing till that particular task ends. On click of stop button, it is again set to 0.

*/


/*
resetVariables function will be called for each of the actions (work, Short Break, Long Break, Stop) to set the value of variables to values corresponding to that particular action
*/

self.resetVariables = function(mins, secs, started){
self.minutes = mins;
self.seconds = secs;
self.started = started;
self.fillerIncrement = 200/(self.minutes*60);
self.fillerHeight = 0;
}

/* handler to be called when user clicks ‘Work’ button */
self.startWork = function(){
self.resetVariables(25, 0, true);
};

/* handler to be called when user clicks ‘Short Break’ button */
self.startShortBreak = function(){
self.resetVariables(5, 0, true);
};

/* handler to be called when user clicks ‘Long Break’ button */
self.startLongBreak = function(){
self.resetVariables(15, 0, true);
};

/* handler to be called when user clicks ‘Stop’ button */
self.stopTimer = function(){
self.resetVariables(25, 0, false);
};

self.timerComplete = function(){
self.started = false;
};

/*
intervalCallback function is called each second, updates the values of minutes and seconds variables and reflect the updates in timer
*/
self.intervalCallback = function(){ 
if(!self.started) return false;
if(self.seconds == 0) {
if(self.minutes == 0) {
self.timerComplete();
return;
}
self.seconds = 59;
self.minutes--;
} else {
self.seconds--;
}

self.fillerHeight += self.fillerIncrement;
};

/* 
toDoubleDigit function converts a number to double digit. If num is single digit (0-9), it is prepended with a ‘0’ and resulting string is returned. If num is double digit, it is returned as such. This function is needed as we want to display ’05’ instead of ‘5’ in timer 
*/
self.toDoubleDigit = function(num){
return num < 10 ? '0' + parseInt(num,10) : num;
};


/*
Init method initializes the timer using $interval function such that a callback function (intervalCallback) is called after every second
*/

self.$onInit = function(){
self.interval = interval( self.intervalCallback, 1000);
/*
$onInit is automatically called when component is initialized. interval variable stores the reference id of the currently running interval. If we need to clear the interval, we will need this variable. Although in the demo, we are not clearing the interval, it’s always a good idea to clear the interval at some point.
*/


};

}]
});

Inside the view, we are using {{toDoubleDigit(minutes)}} to display current minutes in double digits. It is bound to $scope.minutes variable in controller. Thus, as soon as the value of $scope.minutes changes, the changed value is immediately reflected in the view. Same thing happens for seconds and filler height display.

Building the Pomodoro Timer : Angular 2

Now we’re going to build this exact same app using Angular 2.

Angular 2 uses the concept of components which could be considered as Angular 1 directives that are associated with their own template. Let’s go ahead and create the pomodoro app using Angular 2 component. For Angular 2, the angular team has chosen TypeScript over JavaScript. Typescript is a superset of JavaScript and created by Microsoft. So, we will be writing code in TypeScript for the pomodoro app.

html :

Loading…

Note : The following external javascript libraries are required to be added to the page (For the demo, they are already added in copepan settings):

https://npmcdn.com/core-js/client/shim.min.js
//cdnjs.cloudflare.com/ajax/libs/reflect-metadata/0.1.8/Reflect.min.js
//cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.37/system.js
//code.angularjs.org/2.0.0-beta.0/Rx.umd.js
//code.angularjs.org/2.0.0-beta.0/angular2-polyfills.js
//code.angularjs.org/2.0.0-beta.0/angular2-all.umd.dev.js
**typescript :**

/* Import Component object from ng.core */
const {Component} = ng.core;

/* Import Bootstrap object from ng.platform.browser */
const {bootstrap} = ng.platform.browser;

/* Component decorator is used to add metadata to the typescript class*/
@Component({
/*
selector defines the name of the tag which is used to add the component on html page
*/
selector : 'pomodoro-app',

/*
styles defines the css associated with the component
*/
styles : [`
#container{
border:1px solid #333;
border-radius :20px;
width:400px;
margin:20px auto;
padding:20px;
text-align:center;
background : #333;
}

#timer{
color:#f00;
font-size:50px;
margin:10px auto;
border : 5px solid red;
border-radius:50%;
width:200px;
height:200px;
overflow:hidden;
position:relative;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
cursor:default;
}

#time{
margin-top:70px;
z-index : 1;
position:relative;
}

#filler{
background : #ddffcc;
height: 0px;
width: 200px;
position:absolute;
bottom:0;
}

#buttons button {
background:#4da6ff;
border:none;
color:#fff;
cursor:pointer;
padding:5px;
width:90px;
margin:10px auto;
font-size:14px;
height : 50px;
border-radius : 50px;
}

#buttons button#shortBreak{
background : #0c0;
}

#buttons button#longBreak{
background : #080;
}

#buttons button#stop{
background : #f00;
}

`],

/*
template defines the markup associated with the component
*/
template : `

{{toDoubleDigit(minutes)}}
:
{{toDoubleDigit(seconds)}}
 
Work
Short Break
Long Break
Stop
`
})

class AppComponent{
/*
All the variables and functions below have same meaning as described in Angular 1 pomodoro code.
*/
constructor(){
this.started = false;
this.minutes = 25;
this.seconds = 0;
this.fillerIncrement = 200/(this.minutes*60);
this.fillerHeight = 0;
this.init();
}
resetVariables(mins, secs, started){
this.minutes = mins;
this.seconds = secs;
this.started = started;
this.fillerIncrement = 200/(this.minutes*60);
this.fillerHeight = 0;
}
startWork(){
this.resetVariables(25, 0, true);
};
startShortBreak(){
this.resetVariables(5, 0, true);
};
startLongBreak(){
this.resetVariables(15, 0, true);
};
stopTimer(){
this.resetVariables(25, 0, false);
};
timerComplete(){
this.started = false;
}
intervalCallback(){
if(!this.started) return false;
if(this.seconds == 0) {
if(this.minutes == 0) {
this.timerComplete();
return;
}
this.seconds = 59;
this.minutes--;
} else {
this.seconds--;
}
this.fillerHeight += this.fillerIncrement;
};
toDoubleDigit(num){
return num < 10 ? '0' + parseInt(num,10) : num;
};
init(){
self = this;
this.interval = setInterval( function(){
self.intervalCallback.apply(self);
}, 1000);
};
}

/* Bootstrapping the component */
bootstrap(AppComponent, []);

The Angular team has made a lot of changes in Angular 2. It would not be an anomaly to say that they completely revamped the framework and build it from scratch. The reason for doing so many changes was to remove the bad parts of Angular 1 and to take advantage of new features of ECMAScript6 (the new version of JavaScript). Let’s explore the most prominent changes made in Angular 2 and reason behind them.

Controller and scope are completely eliminated from Angular 2. Angular 2 is more focused towards Component based development and object orientation (because of typescript). Web applications nowadays have become too complex. Angular team chose to use web components in Angular 2 because other than providing encapsulation and reusability, web components manages the complexity of the application by providing isolation. Every component is independent of other components and can be used as such by simply importing it on a page. Each component has its own template and styles that will apply only to that particular component. It means that the css will not bleed out of the component. The same is not possible with Angular 1 as the CSS is applied on page level. We can even create custom elements with Angular 2 that could be reused as such or could be extended by other users.

As mentioned earlier, Angular 2 team has chosen typescript for writing code in Angular 2 . The choice is inspired from following facts :

  1. Typescript easily integrates with most of the already existing javascript libraries and existing javascript code. So, we need not worry about legacy code.
  2. Using typescript adds lot of advantages to the framework which includes optional static typing and support for object oriented features like inheritance and interfaces. Static typing allows the type checking during the compilation. An interface define a set of functionality as a contract. When the interface is implemented, all the members of the interface must be implemented. Traditional javascript support prototype-based inheritance which is not completely object oriented. Typescript supports object oriented class based inheritance which goes pretty well with other object oriented features.
  3. Typescript adds type support to javascript. It means that the bugs that are caused by false assumption of a variable being of certain type can be detected while compilation. The same is not possible with javascript as it is dynamically typed.
  4. Typescript is far better than core javascript in managing the complexity of large projects.

Angular 1 implements two-way data binding by dirty-checking method and use watchers to watch the model/view for changes. Higher number of data bindings means higher number of watchers and hence higher performance degradation. Angular 2 doesn’t come with built in two-way data binding, although even in Angular 2, we can create directives that support two-way data binding. Angular 2 primarily uses unidirectional tree based change detection which boosts performance. Although we are not using two way data binding in Angular 1 pomodoro app, its worth mentioning that it is considered to be one of the bad parts of Angular 1 and thus it is removed from Angular 2.

Explore Angular Courses

Because of the optimisations mentioned above, Angular 2 is considered to be 5 times faster as compared to Angular 1 (as per ng-conf [https://ti.to/ng-conf/2016/en]).

In Angular 1, the bootstrapping of the app could be done by using ng-app or by calling the bootstrap function. In Angular 2, it can only be done by calling the bootstrap method.

Angular 1 uses $interval which is Angular’s wrapper for window.setIntervalfunction. As specified in code, the callback function is executed after every 1000 ms. Intervals created by $interval service must be explicitly destroyed because they are not destroyed automatically after the controller scope is destroyed. $interval is not available in Angular 2, thus we can either use javascript’s setInterval orObservable.interval method of Angular 2.

Conclusion

We created two pomodoro apps, one using Angular 1 and other using Angular 2. The app built using Angular 2 carries the advantages of web components and shadow DOM and is also free from the performance degradation caused due to two-way data binding of Angular 1.

Bonus

Here is this pomodoro app done in React

See the Pen Pomodoro Timer : React by Raj Gupta (@rajdgreat007) on CodePen.

Here is this pomodoro app done in Vue

See the Pen Pomodoro Timer : : Vue by Raj Gupta (@rajdgreat007) on CodePen.

Explore Angular Courses

About the Author:

Comparing Javascript & jQuery Through Building a Pomodoro Timer

October 11th, 2016

Modern web development offers an incredible variety of tools, libraries, and frameworks to build web sites/applications. As of 2016, jQuery, React, Angular, and Vue are the most popular front-end libraries/frameworks in use. They can all be used to build and accomplish similar things, but in different ways. What are the advantages/disadvantages of each? How does each approach vary? What do the new tools of React, Vue, and Angular 2 offer that Angular 1, JavaScript, and vanilla JS didn’t?

In this 3 part tutorial series, we’re going to build a simple pomodoro timer as a means to compare vanilla JavaScript, jQuery, React, Angular 1, Angular 2 and Vue.

What is a pomodoro timer?

The pomodoro timer is an easy-to-use productivity method. Using this method, you work in 25 minute spurts with 5 minute breaks in between. Many people find it helpful for helping them focus and work on tasks during the day.

screen-shot-2016-10-11-at-9-31-11-am

Project Overview

In this tutorial, first we will create a pomodoro timer using vanilla javascript. Then, we will re-create the same pomodoro timer using jQuery.

Here is how the final version of pomodoro timer built using vanilla javascript looks like :

See the Pen Pomodoro Timer : : Javascript by Raj Gupta (@rajdgreat007) on CodePen.


Here is how the final version of pomodoro timer built using jQuery looks like :

See the Pen Pomodoro Timer : : jQuery by Raj Gupta (@rajdgreat007) on CodePen.


Our pomodoro timer shows minutes, seconds, and gives simple control buttons. It’s a simple timer but can give enormous productivity gains if used right.

Building the Pomodoro Timer : Javascript

Let’s first write the html code to create various elements of the pomodoro timer.

<div id="pomodoro-app">

 <div id="container">

        <div id="timer">

        <div id="time">

    <span id="minutes">25</span>

    <span id="colon">:</span>

    <span id="seconds">00</span>

        </div>

        <div id="filler"></div>

        </div>

        <div id="buttons">

        <button id="work">Work</button>

        <button id="shortBreak">Short Break</button>

        <button id="longBreak">Long Break</button>

        <button id="stop">Stop</button>

</div>

 </div>

</div>

As you can see, nothing fancy here. Just a container with the timer and control buttons. We will be using a background filler that will keep increasing as time progresses.

Let’s apply some css to the above markup to make it look nice.

#container{

 border:1px solid #333;

 border-radius :20px;

 width:400px;

 margin:20px auto;

 padding:20px;

 text-align:center;

 background : #333;

}

#timer{

 color:#f00;

 font-size:50px;

 margin:10px auto;

 border : 5px solid red;

 border-radius:50%;

 width:200px;

 height:200px;

 overflow:hidden;

 position:relative;

 -webkit-user-select: none;

 -moz-user-select: none;

 -ms-user-select: none;

 user-select: none;

 cursor:default;

#time{

 margin-top:70px;

 z-index : 1;

 position:relative;

}

/*

filler width is set to 200px (i.e. equal to width of the timer) so that it completely covers the timer in background. The height is initially set to 0px and it increases as timer                   progresses to give background fill effect.

*/

#filler{

 background : #ddffcc;

 height: 0px;

 width: 200px;

 position:absolute;

 bottom:0;

}

#buttons button {

 background:#4da6ff;

 border:none;

 color:#fff;

 cursor:pointer;

 padding:5px;

 width:90px;

 margin:10px auto;

 font-size:14px;

 height : 50px;

 border-radius : 50px;

}

#buttons button#shortBreak{

 background : #0c0;

}

#buttons button#longBreak{

 background : #080;

}

#buttons button#stop{

 background : #f00;

}

Now the timer looks nice, but there is no functionality associated with it yet. Let’s add javascript to make it functional.

We will be using object oriented javascript in which all of the variables and functions of the pomodoro timer will be encapsulated inside an object. Below is the basic structure of the code :

var pomodoro = {

           ...………….

           …………….

           init: function() {

               }

           ……………

      …………….

};

//The pomodoro object consists of variables and methods in key value pairs.

window.onload = function() {

     
    pomodoro.init();

};

/* window.onload method is used to make sure that page and DOM are loaded before we call init method as it queries and manipulates DOM. */

Let’ s add variables and other methods which are needed to make the pomodoro timer work.

var pomodoro = {

           
    started: false,

    /*       
started variable stores the state of the timer. If it is true, it means that some task (work, short break, long break) is going on with pomodoro timer. If it is false, it means that the pomodoro is not yet started or it is stopped (by clicking stop button)
     
     */

           minutes: 0,

    /*

            minutes variable stores current minute which is displayed in the pomodoro.       

    */

           seconds: 0,

    /*

            seconds variable stores current second which is displayed in the pomodoro.

    */

           fillerHeight: 0,

    /*

            fillerHeight variable stores the height of the background filler. Initially it is set to 0. As soon as a pomodoro task starts, its height starts increasing (by a value which is stored in fillerIncrement variable) and it keeps increasing till that particular task ends. On click of stop button, it is again set to 0.

    */

           fillerIncrement: 0,

    /*

            fillerIncrement variable stores the value by which fillerHeight should increase.

    */

           interval: null,

    /*

            interval variable stores the reference id of the currently running interval. If we need to clear the interval, we will need this variable. Although in the demo, we are not clearing the interval, it’s always a good idea to clear the interval at some point.

    */

           minutesDom: null,

    /*

            minutesDom : It stores the reference of the minutes element of pomodoro. It’s good to store the reference so that it can be reused instead of querying the DOM again for the same element.

    */

           secondsDom: null,

    /*

            secondsDom variable stores the reference of the seconds element of pomodoro.

    */

           fillerDom: null,

    /*

            fillerDom variable stores the reference of the filler element of pomodoro.

    */

           init: function() {

        /*

                Init method initializes the variables and set event listeners for all buttons. It also starts the interval due to which a callback function (intervalCallback) is called after every 1 second and updates the DOM depending on the task which is in execution.

        */

               
        var self = this;

               
        this.minutesDom = document.querySelector('#minutes'); /* caching the reference to seconds dom object */

               
        this.secondsDom = document.querySelector('#seconds'); /* caching the reference to seconds dom object */

               
        this.fillerDom = document.queryS elector('#filler '); /* caching the reference to background filler dom object */

               
        this.interval = setInterval(function() {

                   
            self.intervalCallback.apply(self);

                   
        }, 1000);



                /* adding the listener to be called when user clicks 'Work’ button */

               
        document.querySelector('#work').onclick = function() {

               
            self.startWork.apply(self);

                   
        };

                /* adding the listener to be called when user clicks 'Short Break’ button */

         
        document.querySelector('#shortBreak').onclick = function() {

                   
            self.startShortBreak.apply(self);

                   
        };

                /* adding the listener to be called when user clicks 'Long Break’ button */

             
        document.querySelector('#longBreak').onclick = function() {

               
            self.startLongBreak.apply(self);

                   
        };

        /* adding the listener to be called when user clicks 'Stop’ button */

             
        document.querySelector('#stop').onclick = function() {

                   
            self.stopTimer.apply(self);

                   
        };

               
    },

    /* resetVariables will be called for each of the actions (work, Short Break, Long Break, Stop) to set the value of variables to the corresponding action values */

           resetVariables: function(mins, secs, started) {

               
        this.minutes = mins;

               
        this.seconds = secs;

               
        this.started = started;

             
        this.fillerIncrement = 200 / (this.minutes * 60);

             
        this.fillerHeight = 0;

               
    },

           startWork: function() {

         
        this.resetVariables(25, 0, true);

               
    },

           startShortBreak: function() {

               
        this.resetVariables(5, 0, true);

               
    },

           startLongBreak: function() {

             
        this.resetVariables(15, 0, true);

               
    },

           stopTimer: function() {

             
        this.resetVariables(25, 0, false);

             
        this.updateDom();

               
    },

           toDoubleDigit: function(num) {

        /*

        If num is single digit (0-9), it is prepended with a '0’ and resulting string is returned. If num is double digit, it is returned as such. This function is needed as we want to display ’05’ instead of '5’ in timer

        */

               
        if (num & lt; 10) {

               
            return "0" + parseInt(num, 10);

                   
        }

               
        return num;

               
    },



    /*

    updateDom function updates the values of minutes, seconds and filler height every second, so that user can see the remaining time and background fill height changing continuously

    */

           updateDom: function() {

             
        this.minutesDom.innerHTML = this.toDoubleDigit(this.minutes);

             
        this.secondsDom.innerHTML = this.toDoubleDigit(this.seconds);

             
        this.fillerHeight = this.fillerHeight + this.fillerIncrement;

             
        this.fillerDom.style.height = this.fillerHeight + 'px';

               
    },



    /*

    intervalCallback function is called each second, updates the value of minutes and seconds variables and calls updateDom function to reflect the updates in timer

    */

           intervalCallback: function() {

             
        if (!this.started) return false;

               
        if (this.seconds == 0) {

               
            if (this.minutes == 0) {

                         
                this.timerComplete();  /* As soon as both minutes and seconds variables become zero, it means that the timer is complete and it can be stopped now*/

                  
                return;

                   
            }

               
            this.seconds = 59;

                   
            this.minutes--;

                   
        } else {

                   
            this.seconds--;

                   
        }

             
        this.updateDom();

               
    },

           timerComplete: function() {

               
        this.started = false;

         
        this.fillerHeight = 0;

               
    }

};

window.onload = function() {

     
    pomodoro.init();

};

Building the  Pomodoro Timer : jQuery

Now we’re going to build this exact same app in jQuery. The HTML and CSS are exactly same as that of above.

var pomodoro = {

/*
All the variables and functions below have same meanings as described in javascript pomodoro code. The difference is only in how we will achieve the same functionality using jQuery code
*/

           
    started: false,

           minutes: 0,

           seconds: 0,

           fillerHeight: 0,

           fillerIncrement: 0,

           interval: null,

           minutesDom: null,

           secondsDom: null,

           fillerDom: null,

           init: function() {

               
        var self = this;

               
        this.minutesDom = $('#minutes');  /*  slower as compared to document.querySelector('#minutes’) */

               
        this.secondsDom = $('#seconds');

               
        this.fillerDom = $('#filler');

               
        this.interval = setInterval(function() {

                      
            self.intervalCallback.apply(self);

                   
        }, 1000);



        /*  adding the click handlers for work, short break, long break and stop buttons */

        $('#work').click(function() {

                   
            self.startWork.apply(self);

                   
        });

             
        $('#shortBreak').click(function() {

                   
            self.startShortBreak.apply(self);

                   
        });

               
        $('#longBreak').click(function() {

               
            self.startLongBreak.apply(self);

                   
        });

         
        $('#stop').click(function() {

               
            self.stopTimer.apply(self);

                   
        });

               
    },

           resetVariables: function(mins, secs, started) {

               
        this.minutes = mins;

               
        this.seconds = secs;

               
        this.started = started;

         
        this.fillerIncrement = 200 / (this.minutes * 60);

         
        this.fillerHeight = 0;

               
    },

           startWork: function() {

         
        this.resetVariables(25, 0, true);

               
    },

           startShortBreak: function() {

               
        this.resetVariables(5, 0, true);

               
    },

           startLongBreak: function() {

         
        this.resetVariables(15, 0, true);

               
    },

           stopTimer: function() {

         
        this.resetVariables(25, 0, false);

         
        this.updateDom();

               
    },

           toDoubleDigit: function(num) {

               
        if (num & lt; 10) {

               
            return "0" + parseInt(num, 10);

                   
        }

               
        return num;

               
    },

           updateDom: function() {

             
        this.minutesDom.text(this.toDoubleDigit(this.minutes));

             
        this.secondsDom.text(this.toDoubleDigit(this.seconds));

               
        this.fillerHeight = this.fillerHeight + this.fillerIncrement;

         
        this.fillerDom.css('height', this.fillerHeight + 'px');

               
    },

           intervalCallback: function() {

         
        if (!this.started) return false;

               
        if (this.seconds == 0) {

               
            if (this.minutes == 0) {

                    
                this.timerComplete();

                  
                return;

                   
            }

               
            this.seconds = 59;

               
            this.minutes--;

                   
        } else {

               
            this.seconds--;

                   
        }

         
        this.updateDom();

               
    },

           timerComplete: function() {

               
        this.started = false;

         
        this.fillerHeight = 0;

               
    }

};

$(document).ready(function() {

     
    pomodoro.init();

});

First of all, I would like to mention that jQuery is a huge library. In our pomodoro app, we have used a very small subset of the features that it offers. This is the biggest disadvantage of using jQuery for our case because we will be loading entire library and because of that, the page load time will be much higher as compared to javascript’s pomodoro app. In huge pages, using jQuery makes a lot of sense.

In the above code we are using $(‘#minutes’) for caching the minutes DOM element.  As a matter of fact, javascript’s document.querySelector(‘#minutes’) is way faster than jQuery’s $(‘#minutes’). This speed difference could not be realised in a small app (such as a pomodoro timer) but it is relevant for large pages where there is intensive DOM query. Javascript’s document.getElementById(‘minutes’) is even faster than document.querySelector(‘#minutes’). So, the speed of executions has the following order :

document.getElementById(‘minutes’)  > document.querySelector(‘#minutes’) > $(‘#minutes’)

The reason for the above speed difference being, under the hood $(‘#minutes’) boils down to document.getElementById(‘minutes’) wrapped by jQuery wrapper. But when we say $(‘#minutes’), jQuery has to a lot of work in identifying if the argument is a string, does it contain spaces, it starts with a ‘.’ or a ‘#’ or is it a tagname and so on. This extra work takes time and hence reduces the speed.

Although, jQuery is at disadvantage because its DOM query speed is less as compared to javascript but when it comes to code convenience, jQuery is far ahead of javascript.

In the pomodoro app created using javascript, we can easily spot long lines of code whereas in the app created using jquery, the code seems relatively short. That means, if we are using jQuery, we have to type less as compared to javascript to achieve the same functionality. Whereas in javascript there are different methods to query DOM (by id, class and tagname), in jQuery, one single selector takes care of all of them.

Moreover,  javascript’s document.querySelector(‘#work’) will not work in all the browsers. It may break in IE8. On the other hand, jQuery’s $(‘#work’) is guaranteed to work in all the browsers. The reason is, all jQuery’s methods are standardised to work across all browsers.

Additionally, jQuery provides support for chaining which means that we can chain a method call at the end of another method call and save few bytes by saving the amount of code required to be written if chaining was not supported. For example, we can do the following in jQuery :

$('#work’).css('background’,’#999’).show()

Here we have chained show() method at the end of css() method. On the other hand, javascript doesn’t support method chaining.

In jQuery, we are using $(document).ready(), to make sure that DOM is ready before we query it. In javascript, we used window.onload event to achieve the same. jQuery’s $(document).ready() event occurs earlier as compared to window.onload of javascript because the latter occurs after the DOM is loaded and all the resources (scripts, images etc) are also loaded.

Last but not the least, while writing javascript code, there is big scope for writing inefficient code. jQuery library on the other hand, is tested over time and highly optimised. Thus, if used carefully, the scope for writing inefficient code using jQery is very less as compared to javascript.

Conclusion

We created two pomodoro apps, one using vanilla javascript and other using jQuery. The two approaches are fairly similar, but jQuery offers an easier syntax in querying for elements and offers shorter (albeit slower) ways of doing things compared to JavaScript.

The differences between libraries/frameworks will get much more interesting in future posts, where we use Angular, React, and Vue to build this same app.

About the Author:

How to change CSS using jQuery?

April 12th, 2016

The jQuery .css method is used to GET or SET DOM element CSS properties.

The following tutorial will demonstrate 4 core concepts of jQuery’s .css method

    1. 1. GET a CSS property from a DOM element
    1. 2. GET multiple CSS properties from a DOM element
    1. 3. SET a CSS property on DOM elements
    1. 4. SET multiple CSS properties on DOM elements

When looking to GET a CSS property with jQuery’s .css method, jQuery will return the first matched element’s CSS properties. So, you will want to pay close attention to the jQuery selector used when requesting a CSS property. If you pass a class into the selector and a group of elements gets returned, jQuery’s .css method will only show CSS properties for the first matched element in the group of matched elements.

Let’s start by taking a look at using jQuery’s .css method to GET a CSS property from a DOM element with a class of box. In this first example, let’s create a <div> with a solid background color

.box {
	background-color: #000;
	width: 100px;
	height: 100px;
	opacity: 0.8;
}

Next, let’s use jQuery’s .css method to GET the opacity of the <div>


	var box_opacity = $('.box').css('opacity');
	console.log(box_opacity) // "0.8"

Note: jQuery’s .css method returns the CSS value as a string, not a number

To return multiple CSS properties, pass in an array of CSS properties. Passing in an array of CSS properties will return an object with CSS key:”value” pairs


var box_props = $('.box').css(['opacity', 'width', 'height', 'background-color']);
console.log(box_props); // Object {opacity: "0.8", width: "100px", height: "100px", background-color: "rgb(0, 0, 0)"}
console.log(box_props.width); // "100px"
console.log(box_props.opacity); // "0.8"

Next, let’s take a look at how to set CSS properties with jQuery. When looking to SET CSS properties, all matched elements returned by the selector will have the css properties defined SET. Setting properties with jQuery’s .css method makes updating a large group of html elements easy. You could update all of paragraph tags in your docuemnt with just one line of code.


$('.box').css('opacity', '0.2');

Finally, setting multiple css properties with jQuery can be done by passing in a javascript object. The key is name of the css property, and the value will be the css value. A good practice is to enclose the keys within quotes to avoid errors with certain css properties such as background-color which has a hyphen between background and color.


$('.box').css({
	'opacity': '1',
	'width': '50px',
	'height': '50px',
	'background-color': '#f48035'
});

To summarize, jQuery’s .css method makes getting and setting css properties with javascript convenient and easy. Whether you are looking to get the font size of some text, or set the width and height of an html element, jQuery’s .css method is a great addition to your tool set. One detail to note when getting a css property, is the css values will get returned as a string. However, when setting a css property such as opacity, width, height, etc.. the .css method conveniently accepts strings or numbers. When setting multiple css properties, a good practice is to wrap your javascript’s object keys in single or double quotes.

About the Author:

JavaScript Events 101

March 24th, 2016

A lot of things happen on webpages. People scroll, click, and move their mouses. Form inputs get entered and typed into. Pages load or get resized. These actions (and many others) are aptly called ‘events’ in web development. And responding to these events is a large part of what makes web applications interactive. Users do things on a page and the page responds in turn. JavaScript is what we use to handle events and give an appropriate response to them.

This post will give a background and overview (with code examples) of how we can handle events with JavaScript. We’ll stay at a relatively high-level so you can quickly learn the gist of events without getting bogged down in minutiae.

Types of Events

Before covering the 3 primary ways of handling JavaScript events, it’s worth knowing what types of events there are. MDN has the one of the easiest to read resources on this. If you go there, you’ll see there’s a ton of different event types! WebMonkey has a nice categorization of them:

  • Page Events
  • Form Events
  • Keyboard Events
  • Mouse Events

I think those are mostly self-explanatory and can help you chunk the events better. You don’t need to know every event in the spec by heart. The big takeaway here is that we can track and respond to just about everything a user might do on a webpage. So what are the primary ways that we can do this? Read on.

Method #1: Event Handlers

Event handlers are the first way that developers respond(ed) to events. Event handlers are also called inline event handlers. That’s because they are put right into the html elements. You’ve probably seen them in the form on onclick or onload.

As you can see here, the onClick handler is put right onto the the anchor element. It will alert ‘welcome’ if it is clicked. Seems pretty straightforward, so what are the disadvantages of this approach?

Disadvantages:

  • Mixing markup with functionality

This breaks the separation of concerns tenet in programming. You generally want to keep JavaScript separate from HTML and not mix the two. This also applies to inline styling with CSS (inline styling is generally bad).

  • You can only put one handler per element

If you need to respond to other types of events on that element, too bad.

  • HTML file size

Putting event handlers in your HTML is going to make your pages a lot heavier.

  • Difficult code maintenance

If you need to make changes to your event handlers you’re going to have to do so on every single element vs. changing things once in a Javascript file.

  • Polluting Global Scope

This is a big No-No in JavaScript. You do not want to put unnecessary methods onto the global object because this could cause collisions if someone else uses the same method name for their code.

So event handlers were what came first and they work but there’s many drawbacks. Event listeners offer us a much better way to do this.

Method #2: Event Listeners (Observer pattern)

This event pattern relies on something called the “observer model”. The observer is the browser. The developer registers event listeners with the browser and says “hey browser, listen up. If this particular action happens, do this (aka run this function)”.

An Element, a Method, an Event, a Function…

The syntax for registering an event listener is pretty simple. Check out this jsfiddle that shows you which event is currently occurring on a page. Here’s an example from that fiddle.

Another way to understand this is imagine the developer is saying “Hey Browser, listen for when someone mouses over the document (the entire page). When they do that, call the sendOutput function. Note: you can register event listeners on any DOM nodes, not just HTML elements.

So event listeners are clearly an improvement over events handlers. So what are the downsides of using them?

  • Performance

Event listeners are not free. Your page/app will slow down when you have to attach Event Listeners to several hundred or thousand nodes.

  • Tedium

It takes a lot of extra work and maintenance to register and track so many event listeners in an HTML document. What if you have list items or particular DOM nodes that are coming and going and changing a lot? With event listeners, you’re going to have to be constantly attaching and removing listeners as the DOM changes.

Event listeners give us a much better syntax but they are also not without their drawbacks.

A note about Bubbling and Capturing

You now need to know a bit about the phases of events. This can be a bit of a rabbit hole so we’ll try to keep this simple and high-level.

An event does not just occur on the element itself. It also occurs on all of its ancestors (parents and grandparents and so on). Let me show you with a code demo or we’ll get lost here otherwise.

What’s happening there? The term is event propagation, which includes capturing and bubbling. Capturing starts at the highest level of the DOM and fires/propagates the event on every ancestor until it hits the exact element where the event occurs. It then does the reverse in a process called bubbling.

Capturing makes a sound like this:

Bubbling, however, sounds like this:

Capturing/Bubbling are a rabbit hole like I said. They have to do with Netscape vs. Microsoft in the 90s and compromises and the chaotic evolution of the technologies that make up our beloved Internet. But we don’t need to go there.

Instead, let’s just focus on bubbling. Bubbling is where an event on a child (e.g. <li>) will propagate up to it’s parents, their parents, and their parents, all the way to the root of the document. Bubbling is what allows us to do event delegation.

Method #3 – Event Delegation

We know events are going to bubble up the DOM. So imagine we have some HTML like this:

<html>

<body>

 <ul>

 <li id="li_1"><button id="button_1">Button A</button></li>

 <li id="li_2"><button id="button_2">Button B</button></li>

 <li id="li_3"><button id="button_3">Button C</button></li>

 </ul>

</body>

</html>

Now imagine that someone clicks on one of those buttons. If we were to use Method #2 (Event Listeners), we’d have to register a separate event listener onto each of those buttons (bleck).

But we know the event will bubble up from the <li> to the <ul> parent. What if we register an event listener on the <ul> and have it figure out which of its children got clicked? This is event delegation in a nutshell. The key is listen on the parents, not the children. Here’s the syntax.

Here’s the code in action. I’m going to use jQuery and explain why later.

jQuery excels at simplifying event delegation. You can, of course, do it in vanilla js but it takes roughly 4-5x as many lines.

In that particular example, I’m logging the event.target.nodeName. But try logging the event.target or just the event to get a sense for what other types of properties the event objects contain.

Here’s another really cool demo I found on CodePen where you can learn more about Bubbling through play:

See the Pen Bubbler – an event bubbling demonstration by Adam McFadden (@adammcfadden) on CodePen.


Summary

This article covered, at a high level, how events can be handled using JavaScript. There’s a lot more to the story then we could cover in 1300 words so below I’m going to put some recommended reading if you’d like to dig in more. That said this should give you enough of a conceptual framework for how events have evolved and how developers use JavaScript to respond to them.

Recommended Reading

Event Delegation – David Walsh Blog

Monitor all JavaScript events in the browser console

Emerging Patterns in JavaScript Event Handling

About the Author:

jQuery Ajax and JSON Envelopes

March 28th, 2015

This is post 3 in a series on creating a JavaScript component for handling your Ajax requests in front-end development across your enterprise. You can find all the other posts here:

In the last post we covered using the publish/subscribe pattern along with some error handling code to add some loosely coupled error messaging and load notifications. We ended with the following code for the component:

var mySiteAjax = ( function( $ ) {
var standardError = "Oops. Sorry about that. Please try again.";

return {
getViaAjax: function( params ) {
var settings = $.extend({
url: '',
spinner: undefined,
dataType: 'html',
cache: false,
success: function(){}
}, params);

var retries = 0;
function ajaxRequest ( ) {
$.ajax({
beforeSend: function(){
$(document).trigger( "ui-load-start.message",
[{ spinner: settings.spinner }] );
},
url: settings.url,
dataType: settings.dataType,
success: settings.success,
complete: function(){
$(document).trigger( "ui-load-end.message",
[{ spinner: settings.spinner }] );
},
error: function( xhr, tStatus, err ) {
if( xhr.Status === "401" || xhr.Status === "403" ) {
//redirect action here
} else if ( xhr.Status === "504" && !retries++ ) {
ajaxRequest();
}
$(document).trigger( "ui-flash.message",
[{ message: standardError }] );
} // end error handler
}); // end $.ajax()
}; // end ajaxRequest()
ajaxRequest();
} // end getViaAjax()
}; // end return statement
})(jQuery);

In this post we are going to take this code and add on some explicit functionality for handling a JSON envelope.

## What is a JSON Envelope
A JSON envelope is a wrapper around JSON returning from the server. The wrapper serves to communicate any failures or messages back to the client along with the appropriate data if the request succeeded.

Consider a scenario where you are sending the server a few parameters and hope to receive a JSON structure back. What happens if you were to send a parameter which was invalid? The server would not be able to respond with the appropriate data and a failure should be communicated.

This is different from an HTTP status code as we were able to communicate with the server successfully. We need a solution to communicate any issues which may have occurred in the server code providing a successful response to our request.

A JSON envelope is a simple mechanism to communicate messages and failures to the client as part of a JSON response. Typically the intended data for the client is wrapped in an object. The JSON object sent back to the client includes this wrapped data if successful. If not the object sent back includes a message. In all cases the response object contains a status indicator.

A typical successful JSON enveloped response might look like this:

{
"status": "ok",
"data": {
"myData": "someData"
}
}

An error response contains a status property as well as a message property indicating the issue:

{
"status": "fail",
"message": "You did not supply the correct input data."
}

Another advantage of using a JSON envelope is that the object wrapper will alleviate a subtle JSON vulnerability (outlined [here](https://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx) by Phil Haack).

### JSON Envelopes in use today

Many public services are implementing JSON envelopes for simple messages and error communication. The [Flickr API](https://www.flickr.com/services/api/) has a JSON envelope in place for simple communication of failures. You can find more information on the [JSON response format](https://www.flickr.com/services/api/response.json.html) page as well as example of [success](https://www.flickr.com/services/rest/?method=flickr.test.echo&format=json&api_key=560f2f65e11cef441ba757d2b509b157) and [failure](https://www.flickr.com/services/rest/?method=flickr.blogs.getList&format=json&api_key=560f2f65e11cef441ba757d2b509b157) responses.

## Handling a JSON Envelope

Our first step is to handle the JSON envelope in our Ajax utility component and take action if a failure occurred. If the envelope indicates a successful response we need to invoke the success callback. As a reminder from last post `settings.success` is the success callback provider by the calling code (or an empty function if none was provided):

var mySiteAjax = ( function( $ ) {
//..
$.ajax({
//...
success: function(wrapper, tStatus, xhr) {
if(!settings.type.match(/^json/i)) {
return settings.success.call( this, wrapper,
tStatus, xhr);
if(wrapper.status === "success") {
return settings.success.call( this, wrapper.data,
tStatus, xhr);
}
$(document).trigger( "ui-flash.message",
[{message: wrapper.message}] );
},
//...
});
//...
})(jQuery);

We have created a success function callback that will be run when the response returns from the server. We will inspect the envelope for a status and will take action if the status is not successful. If it is a success, we will call the success callback provided in our settings.

The code snippet `return settings.success.call( this, wrapper, tStatus, xhr);` is particularly interesting. This may be the first time you have seen the `functionName.call()` method in JavaScript. This method allows us to set the context of the `this` argument in the function call. We could have done the following:

//...
if(wrapper.status === "success") {
setting.success(wrapper.data, tStatus, xhr);
}
//...

But what is the context of `this` in that case? Probably not what the `settings.success` callback would expect. If instead we use the `functionName.call()` JavaScript function we can set the context of `this` as well as all the other arguments for the function call. This allows us to precisely supply the context expected by the `settings.success` function.

To handle the error message we added the following action:

//...
$(document).trigger( "ui-flash.message",
[{message: wrapper.message}] );
//...

We are “publishing” by using jQuery events with a custom event name. Our “message topic” indicates that there is information that should be shared with the user. It is up to another component on our page to have subscribed to this topic and to take the appropriate action. We do not have to care if the message is actually published to the user, or how it is done. We have achieved separation of concerns. Doesn’t it feel nice?

## Handling different JSON Envelopes
Different JSON envelope implementations mean different JavaScript properties and success/failure statuses to deal with. Some sites may not have a JSON envelope. Our utility component needs to handle all these cases.

To do this we will add global settings. This will allow the user to set global defaults while using arguments specified to `mySiteAjax()` if a specific call involves a different JSON envelope.

To handle global setting we will add a settings property onto our mySiteAjax object. The code snippet below is long, but bear with me. We will break it down below.

var mySiteAjax = ( function( $ ) {
var standardError = "Oops. Sorry about that. Please try again.";

// create new Ajax utility as a "private" variable
var myAjax = function( params ) {

// add together global settings with arguments
var params = $.extend({},
myAjax.settings, params);

var retries = 0;

function ajaxRequest ( ) {

$.ajax({
// publish "local" loading start message
beforeSend: function(){
$(document).trigger( "ui-load-start.message",
[{ spinner: params.spinner }] );
},
type: params.type,
url: params.url,
data: params.data,
dataType: params.dataType,
success: function(wrapper, tStatus, xhr) {

// if json is the data type and the json wrapper exists
if( (/^json/i).test(params.dataType)
&& params.env.hasEnv) {
if(wrapper[params.env.statName]
=== params.env.successInd) {

// since wrapper indicated a success,
// call original success callback with the
// unwrapped JSON contents
return params.success.call( this,
wrapper[params.env.dataName],
tStatus, xhr);
}

// success wasn't indicated, publish
// message
$(document).trigger( "ui-flash.message",
[{message: wrapper[params.env.msgName]} ] );
} else {

// return unwrapped if response wasn't json or no envelope
// was specified
return params.success.call( this, wrapper,
tStatus, xhr);
}

},

// publish "local" loading end message
complete: function(){
$(document).trigger( "ui-load-end.message",
[{ spinner: params.spinner }] );
},
error: function( xhr, tStatus, err ) {
if( xhr.Status === "401" || xhr.Status === "403" ) {
//redirect action here
} else if ( xhr.Status === "504" && !retries++ ) {
ajaxRequest();
}
$(document).trigger( "ui-flash.message",
[{ message: standardError }] );
} // end error handler
}); // end $.ajax()
}; // end ajaxRequest()
ajaxRequest();
};

// settings which are global and attached
// to the myAjax function as a property
myAjax.settings = {
url: "",
spinner: undefined,
dataType: "json",
cache: false,
type: "GET",
success: function(){},
env: {
hasEnv: true,
statName: "status",
successInd: "success",
dataName: "data",
msgName: "message"
}
};

//returns the newly created function with the properties attached.
return myAjax;

})(jQuery);

You’ll notice we moved around things. The function is now specified as a named function (although the scope is still within our component code only). We’ve also moved our settings to a property of our main utility function. Since JavaScript functions are objects augmenting it with properties is valid. You’ll also notice that we have an empty object literal as the first parameter to `$.extend()`. This is because the extend method will merge all of the object together and replace the first object with the merged results. We do not want to overwrite our global setting object each time!

Exposing our settings as a property gives us a clean way to specify defaults for a specific page. For example we can set the default HTTP action to POST with minimal effort:

myAjax.setting.type = "POST";

We’ve added settings for the JavaScript envelope. With our settings we can determine whether or not an envelope is used and how to leverage the envelope. Turning off the envelope functionality is now a one line setting:

myAjax.setting.env.hasEnv = false;

In our wrapper code we have changed the way we access objects. For example there is now this snippet:

//...
if( wrapper[params.env.statName]
=== params.env.successInd ) {
//...

Remember that we can access object properties through dot notation or bracket notation. Bracket notation allows you to specify the name of the property as a string. In our above example, with our default global setting of “success” as our status name, the code would evaluate to `wrapper[“success”]`. This would access the success property of the wrapper object. So using this piece of functionality we do not even need to know the names of the properties of our JSON object until runtime!

We now have a working Ajax Utility Component which includes a JSON envelope! I’ve set up a few examples and a playground for the component as a [jsFiddle](https://jsfiddle.net/YLKUz/1/). Please play around and ask questions in the comments!

About the Author:

Do you need jQuery? Can you afford the risk?

March 5th, 2014

appendTo produces a bi-weekly newsletter called the Modern Web Observer that will keep you up to date on trends with the Modern Web. Below is the introduction from Issue #30. You can sign up at https://appendtonew.wpengine.com/mwo

It seems that the issue of, “Do you need jQuery”, makes the headline rounds every few months. I always giggle when I see these posts, because they try to make the point that browsers have evolved to the place where native JavaScript methods can replace jQuery methods.

Measure by risk

Our position here at appendTo, as on many things in the Modern Web, comes down to risk.

  • Can you afford the added cost and added risk to build a production level project without jQuery?
  • Do you want to depend on Browser API’s staying consistent for the entire lifecycle of your Modern Web application?

Your answer may be different. For any serious application, we wouldn’t take the risk and we don’t think you should either.

FluentConf 2014

We’re incredibly excited to be participating in FluentConf next week. Fluent has emerged as one of our favorite Modern Web events and if you’re attending, please stop by our booth to say hi. Our own VP of Training, Ralph Whitbeck, is speaking on “Performance Tips when Developing with jQuery Mobile” on Thursday at 12:00pm. See you there!