Posts Tagged ‘tutorials’

Handle Mouse And Touch Input With The Pointer Events API

Tuesday, April 18th, 2017

pointer-events-api-2

With more and more people using their mobile phones and tablets for web browsing, we as developers have to make sure that our web interfaces are fully accessible via touch. Setting up click and hover event listeners sort of works, but it is clearly a leftover solution from the mouse era.

Thankfully, there is a new API in town that accommodates the needs of mouse, touch, and stylus devices. It’s called Pointer events (not to be mistaken with the CSS property of the same name) and it allows us to add event listeners that are better suited for working with all types on input.

Meet The New Events

The new Pointer Event API is an evolved version of the Mouse Event interface we’ve all been using so far. It extends the functionality of the old API and adds support for multi-touch gestures, precise pen input, and overall smoother touchscreen interaction.

Most of the Pointer Events have direct alternatives among the old mouse events. Once the new API gets full browser support we can directly substitute with the more modern alternatives:

const button = document.querySelector("button");

// Instead of mouseover
button.addEventListener('mouseover', doSomething);

// We can use pointerover
button.addEventListener('pointerover', doSomething);

Interacting with a mouse should be the same in both cases. Using fingers or a stylus, however, will be easier to program with the new API.

Recognizing Input Type

An awesome feature of the Pointer Events API is that it can tell which type of input has been used. This can be helpful when you want to ignore some of the input methods or provide special feedback for each one.

button.addEventListener('pointereover', function(ev){
  switch(ev.pointerType) {
    case 'mouse':
      // The used device is a mouse or trackpad.
      break;
    case 'touch':
      // Input via touchscreen.
      break;
    case 'pen':
      // Stylus input.
      break;
    default:
      // Browser can't recognize the used device.
      break;
  }
});

Other Properties

The Pointer Events interface provides some some other interesting data as well. It includes all the MouseEvent properties plus the following:

Mouse clicks always have a width and height of 1, touch size differs.

Mouse clicks always have a width and height of 1 while touch size varies.

Browser Support

Pointer Events are fairly new, so browser compatibility isn’t perfect yet. Chrome (desktop and mobile), Edge, IE, and Opera have full support; Firefox and Safari don’t.

Pointer Events Browser Compatibility on Can I Use

Pointer Events Browser Compatibility on Can I Use

To check whether a browser has the Pointer Events API you can use the window object:

if (window.PointerEvent) {
  // Pointer Events enabled.
} else {
  // Pointer Events not supported
}

A popular open-source pollyfill is also available for those who don’t want to wait for full browser adoption.

Conclusion

Although it doesn’t have full browser support yet, the Pointer Events API is eventually going to take over the old mouse events. It provides a lot of cool features that will increase web accessibility and enable developers to create more advanced touch and stylus-based apps.

If you want to learn more about the Power Events API we recommend checking out these resources:

Tags: , , , ,
Posted in PHP Tutorials | No Comments »

Learn Webpack in 15 Minutes

Monday, April 10th, 2017

learn-webpack-in-15

Build tools have become an integral part of web development, mainly due to the ever-increasing complexity of JavaScript apps. Bundlers allow us to package, compile, and organize the many assets and libraries needed for a modern web project.

In this tutorial we will take a look at webpack, a powerful open-source bundler and preprocessor that can handle a huge variety of different tasks. We’ll show you how to write modules, bundle code, and use some of the loader plugins. The tutorial is designed for total beginners to webpack, but having some JavaScript knowledge is advised.

webpack-logo

Why webpack?

Much like any other aspect of web development, there isn’t a standard for which build tool to use. Right now, developers have to choose between webpack, Gulp, Browserify, NPM scripts, Grunt, and like 10 others. There are many in-depth comparisons out there, but all of these tools are very similar, so most of the time it comes down to personal preference and what project you are working on.

Here are some pros and cons to help you decide whether webpack is the tool for you:

Pros:

Cons:


1. Installation

The easiest way to install webpack is by using a package manager. We will go with npm but feel free to use Yarn or another hip alternative. In both cases you need to have Node.js on your machine and a package.json ready to go.

It is preferred to install it locally (without the -g tag). This will make sure everyone working on your project has the same version of webpack.

npm install webpack --save-dev

Once we have it installed, it’s best to run webpack via a Node.js script. Add these lines to your package.json:

//...
    "scripts": {
        "build": "webpack -p",
        "watch": "webpack --watch"
    },
//...

Now by calling npm run build from the terminal we can make webpack bundle our files (the -p option stands for production and minifies the bundled code). Running npm run watch will start a process that automatically bundles our files when any of them change.

The last part of the setup is to tell webpack which files to bundle up. The recommended way to do this is by creating a config file.


2. Webpack Config File

Here we will look at the config file in its most basic form but don’t let that fool you – the webpack config file is quite powerful, varies a lot from project to project, and can become super complex in some cases.

In the root directory of your project add a file called webpack.config.js.

webpack.config.js

var path = require('path');

module.exports = {
  entry: './assets/js/index.js',
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist')
  }
};

The entry option tells webpack which is our main JavaScript file. There are many different strategies for configuring entry points but in most cases a single entry is enough.

In output we specify the name and path of our bundle. After running webpack we will have all our JavaScript in a file called bundle.js. This is the only script file that we will link in our HTML:

<script src="./dist/bundle.js"></script>

This setup should be enough to get us started. Later we will add some more stuff to it, but first let’s see how modules work.


3. Webpack Modules

Webpack provides multiple ways to work with modules, and most of the time you are free to go with whichever one you like. For this tutorial we will use the ES6 import syntax.

We want to add a module that greets our users. We create a file called greeter.js and make it export a simple function:

greeter.js

function greet() {
    console.log('Have a great day!');
};

export default greet;

To use this module, we have to import it and call it in our entry point, which if you look back at the config file is index.js.

index.js

import greet from './greeter.js';

console.log("I'm the entry point");
greet();

Now when we run the bundler with npm run build, and open our HTML in the browser, we see this:

console-greet

Our entry point and our greeter module were compiled into one file called bundle.js and it was executed by the browser. Here is a simple flow chart of what’s happening so far:

webpack-flow-1


4. Requiring Libraries

We want our app to specify which day of the week it is when it greets users. To do so we will use moment.js by directly importing it into our greeter module.

First we need to install the library via npm:

npm install moment --save

Then in our greeting module, we simply import the library exactly the same way we imported local modules in the previous point:

greeter.js

import moment from 'moment';

function greet() {
    var day = moment().format('dddd');
    console.log('Have a great ' + day + '!');
};

export default greet;

After we bundle up again to apply the changes, in the browser console we will have the following messages:

weekday-greet

Our flow diagram now looks like this:

webpack-flow-2

Note: There are other, more advanced techniques for including libraries but they are outside the scope of this article. You can read more about them here.


 5. Loaders

Loaders are webpack’s way to execute tasks during bundling and pre- or post-process the files in some manner. For example, they can compile TypeScript, load Vue.js components, render templates, and much more. Most loaders are written by the community, for a list of popular loaders go here.

Let’s say we want to add a linter to our project that checks our JS code for errors. We can do so by including the JSHint loader, which will catch all kinds of bad practices and code smells.

First we need to install both JSHint and the webpack JSHint loader:

npm install jshint jshint-loader --save

Afterwords, we are going to add a few lines to our webpack config file. This will initialize the loader, tell it what type of files to check, and which files to ignore.

webpack.config.js

var path = require('path');

module.exports = {
  entry: './assets/js/index.js',
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist')
  },
  // Add the JSHint loader
  module: {
    rules: [{
      test: /\.js$/, // Run the loader on all .js files
      exclude: /node_modules/, // ignore all files in the node_modules folder
      use: 'jshint-loader'
    }]
  }
};

Now when webpack is started, it will show us a list of warnings in the terminal (which we will ignore):

terminal-warnings

Since moment.js is located in the node_modules folder, it won’t be linted by the JSHint loader:

webpack-flow-3


Further Reading

This concludes our introduction to webpack! Since this is a lesson for beginners, we tried to cover only the most useful and must-know concepts of webpack. We hope the tutorial has been helpful, not too confusing, and within the 15 minute limit from the title.

In the near future, we are planning to add a second part to this tutorial, explaining how to work with CSS modules and other more-advanced features. In the meantime, if you want to learn more about webpack (and there is a lot more) we recommend checking out these awesome resources:

Tags: , , , ,
Posted in PHP Tutorials | No Comments »

Quick Tip: Accessing The Clipboard With JavaScript

Monday, October 10th, 2016

accessing-the-clipboard-with-js_

In this article we’re going to show you how to use simple vanilla JavaScript snippets to:

  1. Add text to the clipboard on user action, such as the press of a button.
  2. Modify the content of the clipboard when a user copies something.

The APIs we will be using don’t require any external libraries, and have almost perfect browser compatibility!

Copy On Click

An awesome accessibility feature you can add to your website is the ability to copy strings directly via button press. This interaction can be applied to quickly grab URLs, long strings such as SSH keys, terminal commands, hex colors, or any other data that is frequently copy & pasted.

To make this happen we will need to use a cool JavaScript method called execCommand(). It allows us to invoke a number of different events that manipulate editable content such as making text bold/italic, doing undo/redo, and also copy/cut/paste.

document.execCommand('copy');

This works exactly like pressing CTRL/Cmd+C on your keyboard, so in order to copy any text we first need to have it selected. This is possible in JavaScript thanks to the Selection API, which allows us to programatically make a text selection from any HTML element on the page.

var button = document.getElementById("copy-button"),
    contentHolder = document.getElementById("content-holder");

button.addEventListener("click", function() {

    // We will need a range object and a selection.
    var range = document.createRange(),
        selection = window.getSelection();

    // Clear selection from any previous data.
    selection.removeAllRanges();

    // Make the range select the entire content of the contentHolder paragraph.
    range.selectNodeContents(contentHolder);

    // Add that range to the selection.
    selection.addRange(range);

    // Copy the selection to clipboard.
    document.execCommand('copy');

    // Clear selection if you want to.
    selection.removeAllRanges();

}, false);

To see the example in action check out the editor below:

(Play with our code editor on Tutorialzine.com)

In the example above the content we want to copy is simply stored in a paragraph. If the text you need is not on the page, you will need to first write it in an element hidden off-screen.

Modify Copied Text

Here we will show you how to manipulate content in the clipboard after it’s been copied. This can be very useful for escaping code, formatting numbers and dates, or for other text transformations such as uppercase, lowercase, etc.

JavaScript provides us with copy() and paste() events, but they are designed in such a way that the content stored in the clipboard is secure:

Since we want to read and write at the same time, we will need to use the Selection API once more. Here is the solution:

document.addEventListener('copy', function(e){

    // We need to prevent the default copy functionality,
    // otherwise it would just copy the selection as usual.
    e.preventDefault();

    // The copy event doesn't give us access to the clipboard data,
    // so we need to get the user selection via the Selection API.
    var selection = window.getSelection().toString();

    // Transform the selection in any way we want.
    // In this example we will escape HTML code.
    var escaped = escapeHTML(selection);

    // Place the transformed text in the clipboard. 
    e.clipboardData.setData('text/plain', escaped);

});

You can try the code in the editor below:

(Play with our code editor on Tutorialzine.com)

Further Reading

In this quick tip we presented you two useful snippets for working with the clipboard in pure vanilla JavaScript. We used a bunch of hip native APIs, so here they are again if you want to read more about them:

Also, if you need more control over copy/paste/cut events, you can use a library such as clipobard.js. It has lots of features and provides a nice clean API for managing the clipboard.

We hope you enjoyed this article! Feel free to ask question or leave suggestions in the comment section below :)

Tags: , , , ,
Posted in PHP Tutorials | Comments Off on Quick Tip: Accessing The Clipboard With JavaScript

Everything You Should Know About Progressive Web Apps

Tuesday, September 27th, 2016

progressive-web-apps_1

Progressive Web Apps is a web application which takes advantage of modern browser features and can be added to your homescreen, behaving just like a native application.

In this tutorial we’re going to show you everything you need to know about PWAs, step by step, with practical examples and a demo app. To not start from scratch, we are going to use the selfie app we made recently, and make it progressive.


What is a Progressive Web App

In its core a progressive web app isn’t any different from a normal website – it’s made of HTML, CSS and JavaScript, and lives in the browser. What separates PWAs from regular websites is a list of 10 key concepts that need to be fulfilled. Here they are, taken directly from the Google Developers website.

  1. Safe – Served via HTTPS to prevent snooping and ensure content hasn’t been tampered with.
  2. Progressive – Work for every user, regardless of browser choice because they’re built with progressive enhancement as a core tenet.
  3. Responsive – Fit any form factor: desktop, mobile, tablet, or whatever is next.
  4. Connectivity-independent – Enhanced with service workers to work offline or on low quality networks.
  5. App-like – Feel like an app to the user with app-style interactions and navigation because they’re built on the app shell model.
  6. Fresh – Always up-to-date thanks to the service worker update process.
  7. Discoverable – Are identifiable as “applications” thanks to W3C manifests and service worker registration scope allowing search engines to find them.
  8. Re-engageable – Make re-engagement easy through features like push notifications.
  9. Installable – Allow users to “keep” apps they find most useful on their home screen without the hassle of an app store.
  10. Linkable – Easily share via URL and not require complex installation.

Following these guidelines will ensure that your app works well not only when viewed in the browser, but also when started separately via a home screen shortcut. You may find the wording Google has chosen rather confusing, but don’t worry, we will explain the rules one by one later in the tutorial.


What a Progressive Web App is NOT

The concept of PWAs shouldn’t be confused with:

All of the aforementioned technologies wrap HTML apps and package them into executable files, be it an .apk, .exe or anything else, which then have to be downloaded from the respective app store and installed on the user’s device.

PWAs don’t require installation and aren’t available (yet) in Google Play or the iTunes App store. To download a PWA you need to simply visit it’s website and then save it to the home screen as a shortcut. Developing and maintaining separate iOS and Android versions is no longer an issue, but browser support needs to be taken into consideration.


1_safe1. Safe

Most progressive web apps work with native APIs and service workers, technologies that deal with sensitive data and need to be handled with caution. That’s why every PWA has to be served through a HTTPS connection.

If you don’t have access to a server with a SSL certificate, the easiest way run projects in a secure environment is via GitHub Pages or a similar service. Any GitHub repository can be hosted directly over HTTPS, and both GitHub and GitHub Pages are free for public repos.

This is where we’ve chosen to host our demo: https://tutorialzine.github.io/pwa-photobooth/.

For simple testing on a local server, you can also try Ngrok. Its a tiny tool that allows you to tunnel any currently running localhost to a secure public URL. Ngrok is free and available for Windows, Mac, and Linux.


2_progressive

2. Progressive

Essentially, what this means is that PWAs should use web technologies that are widely supported and work equally well on as many browsers as possible. As we all know, in the world of web development this is close to impossible, but still there are things we can do to cover a larger user base.

For example, in our PhotoBooth app we use the getUserMedia() API for accessing the hardware camera on a device. Its support in different browsers is quite inconsistent – Safari doesn’t support it at all, the browsers that do support it need prefixes and differ in usage.

To ensure more people can actually use our app, we cover all the prefixes:

navigator.getMedia = ( 
    navigator.getUserMedia ||
    navigator.webkitGetUserMedia ||
    navigator.mozGetUserMedia ||
    navigator.msGetUserMedia
);

We also show an error if none of the prefixes work:

if (!navigator.getMedia) {
    displayErrorMessage("Your browser doesn't have support for the navigator.getUserMedia interface.");
}
else {
    // Use Camera API
}

Fallbacks and polyfills should be provided where possible. The same principles go for the CSS and HTML code.


3_responsive

3. Responsive

The app should look nice on all devices, no matter their screen size. Our app has a fairly simple UI so we’ve used only a couple of media queries to control font-size, paddings, margins, etc.

Don’t be afraid to use CSS libraries and frameworks such as Bootstrap, as they make it really easy to form grids, and deal with typography and general responsiveness.


4_offline

4. Connectivity independent

This is an important one. Using service workers allows your app to work even when there is no internet connection available.

Some apps can be cached only partially: UI is cached and available offline, dynamic content still needs access to a server.

Others, like our PhotoBooth demo, can be cached in their entirety. All of the source code and resources will be saved locally and the app will work offline and online exactly the same way. Here is the code that makes the magic happen:

This is an oversimplified usage of Service Workers, use with caution in commercial projects.

First we need to make a service worker JavaScript file, and define the logic behind it.

sw.js

// Install the service worker.
this.addEventListener('install', function(event) {
    event.waitUntil(
        caches.open('v1').then(function(cache) {
            // The cache will fail if any of these resources can't be saved.
            return cache.addAll([
                // Path is relative to the origin, not the app directory.
                '/pwa-photobooth/',
                '/pwa-photobooth/index.html',
                '/pwa-photobooth/assets/css/styles.css',
                '/pwa-photobooth/assets/fonts/MaterialIcons-Regular.woff2',
                '/pwa-photobooth/assets/js/script.js',
                '/pwa-photobooth/assets/icons/ic-face.png',
                '/pwa-photobooth/assets/icons/ic-face-large.png',
                '/pwa-photobooth/manifest.json'
            ])
            .then(function() {
                console.log('Success! App is available offline!');
            })
        })
    );
});


// Define what happens when a resource is requested.
// For our app we do a Cache-first approach.
self.addEventListener('fetch', function(event) {
    event.respondWith(
        // Try the cache.
        caches.match(event.request)
        .then(function(response) {
            // Fallback to network if resource not stored in cache.
            return response || fetch(event.request);
        })
    );
});

Then we need to link that service worker to our HTML.

index.html

<script>
// Register Service Worker.

if ('serviceWorker' in navigator) {
    // Path is relative to the origin, not project root.
    navigator.serviceWorker.register('/pwa-photobooth/sw.js')
    .then(function(reg) {
        console.log('Registration succeeded. Scope is ' + reg.scope);
    })
    .catch(function(error) {
        console.error('Registration failed with ' + error);
    });
}
</script>

Now all of the files in our project will be saved in the user’s browser. Any JavaScript variables and object should also be saved in the localStorage or IndexDB where possible.

Right now Service Workers are supported in Chrome, Firefox and Opera. Safari and Edge are also working towards adopting them, and we hope that in the future they will be available in every browser.


5_applike

5. App-like

When building PWAs, it’s recommended to follow a design concept called app-shell architecture. It sounds very complicated but essentially boils down to this: the app is separated into two major components: the shell and the content.

The shell contains all the static UI elements such as a header, menus, drawers, etc. When we cache an app, the shell should always be saved on the device, because we want it to be available at all times. That way when a user with no internet connection opens the app, they won’t see an empty screen or a running dinosaur – they will see the cached app interface and an appropriate error message.

Image Courtesy To developers.google.com

The content resides within the shell. It can also be cached but it isn’t necessary to do so as content is usually dynamic, changes frequently and can be different on every single page load.


6_fresh_

6. Fresh

Once cached, our PWA will always load from the local storage. However, if we change the service worker sw.js in any way, on the next page load the new version will be downloaded and installed.

this.addEventListener('install', function(event) {
    event.waitUntil(
        caches.open('v1.0.1').then(function(cache) {
            // ...
        })
    );
});

Using service worker updates we can re-download resources, delete old cache, or completely change the service worker logic. You can learn more about the SW Update process from this Google Developers article – here.


7_discoverable_

7. Discoverable

By adding a Web Manifest to our app we can provide various information about it and change the way it is displayed on people’s devices. It allows apps to be saved to the home screen with a custom icon, to be started in a separate browser window, and a lot of other cool stuff.

The Web Manifest takes the form of a simple JSON file:

manifest.json

{
  "name": "Progressive Web App: PhotoBooth",
  "short_name": "PhotoBooth",
  "description": "Simple Progressive Web App for taking selfies.",
  "icons": [{
      "src": "assets/icons/ic-face.png",
      "type": "image/png",
      "sizes": "72x72"
    }, {
      "src": "assets/icons/ic-face-large.png",
      "type": "image/png",
      "sizes": "144x144 256x256" 
    }],
  "start_url": "index.html",
  "display": "standalone",
  "background_color": "#fff",
  "theme_color": "#fff",
  "orientation": "portrait"
}

Most of the properties are self explanatory so we will cover only the more important ones. To see the full Web manifest format and all the available fields go here.

To register the manifest we have to link it to our HTML:

<!-- Web Manifest -->
<link rel="manifest" href="manifest.json">

Safari doesn’t support the Web Manifest standard yet but we can define app-like behavior with this Apple-specific meta tag:

<!-- Meta tag for app-like behaviour in iOS -->
<meta name=”apple-mobile-web-app-capable” content=”yes”>

8_notifications

8. Re-engageable

Push notifications aren’t limited to native apps any more. Thanks to service workers and the Push API, web applications can also send messages to the Android notification bar. Not all apps will benefit from having this feature, but when used properly notifications can really help engage users.

This topic goes beyond the scope of our tutorial, as Push Notifications are quite complicated and deserve a full lesson on their own. If you still want to implement notifications to your web app, here are some of the best learning resources available:


9_installable_

9. Installable

By default any website can be manually saved to the home screen using the Add to Home Screen button from the Chrome browser menu. However, it might be rather difficult to make users “install” our app this way, since most people don’t know about that feature at all.

Thankfully, there is a way for your app to prompt users to save it with a simple installation pop-up. To prevent developers from abusing these pop ups, there isn’t any way to programmatically show them. Instead, they will appear on their own when an app fulfills a series of requirements:

  1. There is a valid Web Manifest.
  2. There is a valid Service Worker installed.
  3. The app is served over HTTPS.

We have all of the above covered, so when a user visits our app’s website a couple of times, they will get this prompt:

Add To Homescreen Prompt

Add To Homescreen Prompt

The entire installation process of our app is in this simple prompt. The install happens instantly, and once saved the PhotoBooth will be available to launch from a home screen icon, behaving exactly like a native app.


10_linkable_

10. Linkable

Anyone with a web browser has access to PWA apps and they can be shared simply via their URL. No third party tools are required for finding or installing them.

If an app runs in standalone mode, it’s also advisable to add in-app share buttons, since the browser address bar and menus aren’t visible.


Conclusion

Our PWA is now complete. We can test how well it follows the PWA rules with an official Google-made tool called Lighthouse. It recreates possible scenarios and tests the app thoroughly. Here is what it tells us about the PhotoBooth:

Lighthouse Report

Lighthouse Report

We passed!

If you want to find more PWAs to play with, go to pwa.rocks. They offer a nice collection of games and useful tools, showcasing the great power of Progressive Web Apps.

Tags: , , , ,
Posted in PHP Tutorials | Comments Off on Everything You Should Know About Progressive Web Apps

Quick Tip: Working with the JavaScript Battery API

Tuesday, August 23rd, 2016

working-with-js-battery-api

In this tutorial we’re going to show you how to use the JavaScript Battery API to improve the user experience for people in desperate need of a charger. We’ll look at the Battery API itself, as well as some techniques for getting the most out of every drop of the most precious of resources!

Monitoring Battery Life

The JavaScript Battery Status API talks to the device’s hardware and gives us accurate data about the system’s charging state. It can be accessed via the promise based navigator.getBattery() interface, or directly via the navigtator.battery object, although the second option is now deprecated and overall not recommended.

Some browsers lack support for the Battery API (you guessed it, they are Safari and IE), so a quick support check can go a long way in terms of debugging:

if(navigator.getBattery){
    // Battery API available.
    // Rest of code goes here.
}
else{
    // No battery API support.
    // Handle error accordingly.
}

Once we are sure that your user can access the API, grabbing the needed information is really easy:

navigator.getBattery()
    .then(function(batteryManager) {
        
        // Get current charge in percentages.
        var level = batteryManager.level * 100;

    })
    .catch(function(e) {
        console.error(e);
    });

The getBattery() method returns a promise and resolves with a BatteryManager object containing various information about the current status of the hardware:

It also provides events that can be used to monitor changes in any of the above properties.

Combining the raw data with the event listeners, we can easily set up a watcher for low battery levels:

navigator.getBattery()
    .then(function(battery) {    
        battery.onlevelchange = function() {

            if(battery.level<30 && !battery.charging) {
                powerSavingMode = true;
            }

        }
    });

Once we know how much juice is left in the device we can adapt the app and turn on a power saving mode if its needed.

Preserving energy

The biggest battery drainer of all components is the screen. This is especially true on smartphones and tablets where often CPUs are energy preserving, while the screens have super-ultra-full-QHD resolution with the brightness of two suns.

The first and foremost thing we can do to address this issue is limit the amount of light the screen is emitting. JavaScript doesn’t have the authority to control the brightness directly, but we can do so by changing the color pallet to a darker theme.

dark-theme

Dark colors need less energy to be displayed, with more than 50% reduction on AMOLED screens.

The next thing we can do is limit the amount and size of requests to external resources. The biggest drainers here are high-res images, advertisements, and large JavaScript libraries, as they need a lot of bandwidth to download.

Here we have two options – load an alternative, more optimized resource with a smaller footprint, or, fully remove the image/advert if it doesn’t portray any essential information. Any background images, videos or animations should be removed.

removed-ads

Removing non-essential elements from the page makes the vital content easier to reach when in a hurry.

The last battery-drainer we will talk about is JavaScript. We already mentioned that download large libraries and frameworks is bad enough, but the actual parsing and execution of JS block can also lead to unnecessary spending.

JavaScript animations that cause constant redrawing of elements on the screen, listening for notifications form the server, and multiple AJAX requests can all drain the battery just a tiny bit, but it quickly adds up. According to this study, the JavaScript code consumes ~7% of Yahoo’s total rendering energy, ~17% on Amazon, and more than 20% on YouTube.

App With Powersaving Mode

We have showcased some of the above concepts in a simple demo app. It consists of a static website which reacts to the amount of battery left. When it gets below 30% the app goes into PowerSaving and turns darker, stops all animations, and removes all ads.

For demonstration purposes our app works with a virtual battery to enable quick toggling between fully charged and almost dead. It does not contain much code for working with the Battery API itself.

Our Demo App

Our Demo App

You can get the full code for the demo from the Download button near the top of the article. It’s written in Vue.js for easier data monitoring and has lots of comments to guide you through all that is happening.

Further Reading

If you want to find out more about the Battery Status API or about ways your precious battery is running down the drain, check out these excellent resources:

Battery Status API on MDN – here
The BatteryManager interface on MDN – here
5 Ways to Improve Battery Life in Your App – here
Who Killed My Battery: Analyzing Mobile Browser Energy Consumption – here

Tags: , , , ,
Posted in PHP Tutorials | Comments Off on Quick Tip: Working with the JavaScript Battery API

Building Your First App With Vue.js

Monday, August 8th, 2016

building-your-first-app-with-vuejs

Today we’re going to exercise our Vue.js skills by building a simple app for browsing reddit posts. We’re going to construct the whole thing from scratch to demonstrate just how easy it is to create user interfaces with a framework like Vue.

This tutorial requires you to have at least some basic knowledge of JavaScript and Vue.js. If you aren’t familiar with Vue.js at all, we advise you to go and check out our article 5 Practical Examples For Learning Vue.js, where we show many of the core concepts with practical code snippets.

The App

What we want from our application is simply to fetch the feed from a number of subbreddits and display them. Here is what the end result will look like:

vue-app

Our Vue.js App

We will have six separate subreddit feeds showing five posts each. The posts have links to the content and discussion on reddit, as well as some other details. For the sake of simplicity we have omitted features such as adding/removing subreddits and doing searches, but they can be easily added on top of the existing app.

Setting Up The Workspace

You can download the full source code for the reddit browser app from the Download button near the top of the article. Before we actually look at the code, let’s make sure that everything is setup properly. Here is an overview of the file structure:

Our project's folder

Our project’s folder

As you can see it’s quite basic: we just have one HTML file, one CSS file, a script.js containing our JavaScript code. We’ve also added local copies of the Vue.js and Vue-resource libraries, but you can use a CDN if you prefer.

Thankfully, Vue.js doesn’t require any special configuration, so it should work straight out of the box. To start the app we just have to create a global Vue instance:

new Vue({
    el: 'body'
});

The only thing left to do now is start a local web server to enable cross-origin AJAX requests to the reddit API. The easiest way to do this on OS X/Ubuntu is by running the following command from the project’s directory:

python -m SimpleHTTPServer 8080

If everything is done properly our project should be available at localhost:8080.

Creating Custom Components

Our app is going to need two reusable components – one for the Posts, and another for Subreddits. The two components will be in a Child-Parent relationship, meaning that the Subreddit component will have multiple Posts nested in it.

Components Structure

Components Hierarchy

Let’s start with the Subreddit component, and more specifically it’s JavaScript:

// Parent | Subreddit component containing a list of 'post' components. 
var subreddit = Vue.component('subreddit',{
    template: '#subreddit',
    props: ['name'],

    data: function () {
        return { posts: [] }
    },

    created: function(){
        this.$http.get("https://www.reddit.com/r/"+ this.name +"/top.json?limit=5")
        .then(function(resp){
            this.posts=resp.data.data.children;
        });
    }
});

Here we define the new component under the name subreddit. In props we provide an array with all the parameters our component can receive – in this case it is just the name of the subbreddit we want to browse. Now if we want to add a subreddit block to the HTML we will use this markup:

<subreddit name="food"></subreddit>

The data property defines what variables are needed for each instance of the component and their default values. We will start with an empty posts array, and populate it in the created method. When a <subreddit> tag is created, Vue will take its name property, make a call to the reddit API to fetch the top 5 posts from the subreddit with that name, and save them in this.posts. For the HTTP requests we’ve used the vue-resource library instead of jQuery, since it is way tinier and automatically binds the correct context for this.

After we’ve acquired everything we need in the model, Vue.js will automatically render our Subreddit components. The actual view that the user sees is defined in a template in index.html:

<template id="subreddit">

    <div class="subreddit">
        <h2>{{ name | uppercase }}</h2>

        <ul class="item-list">
            <li v-for="obj in posts">
                <post :item="obj"></post>
            </li>
        </ul>
    </div>

</template>

Personally, I like to wrap all the elements of a component in a div container. This makes them easier to style and also seems more semantic (to me at least). Inside that container we have a title (the uppercase filter comes built-in with Vue) and an unordered list iterating over the elements returned from the reddit API call.

If you look closely at the HTML, you’ll also notice we are using a <post> tag. This isn’t some new fancy HTML element – it’s our child component!

// Child | Componenet represiting a single post.
var post = Vue.component('post', {
    template: "#post",
    props: ['item']
});

Post components will expect a object called item containing all of the information about a single post on reddit – things like title, URLs, number of comments, etc. As we saw earlier, this is done in a v-for loop inside the Subreddit (parent) component:

<li v-for="obj in posts">
    <post :item="obj"></post>
</li>

The colon prefixing :item="obj" is very important. It tells Vue that we are proving a JavaScript object called obj (as opposed to the string "obj"), allowing us to pass the data from the v-for.

Now that we have all the needed properties for a post, we can display them. The template looks scary at first, but really isn’t:

<template id="post">

    <div class="post">
        <a   :href="item.data.url" :style="item.data.thumbnail | setAsBackground" 
             target="_blank" class="thumbnail"></a>

        <div class="details">
            <a :href="item.data.url" :title="item.data.title" target="_blank" class="title">
                {{ item.data.title | truncate}}
            </a>          
            
            <div class="action-buttons">
                <a href="http://reddit.com{{ item.data.permalink }}" title="Vote">
                    <i class="material-icons">thumbs_up_down</i>
                    {{item.data.score}}
                </a>

                <a href="http://reddit.com{{ item.data.permalink }}" title="Go to discussion">
                    <i class="material-icons">forum</i>
                    {{item.data.num_comments}}
                </a>
            </div>
        </div>
    </div>
    
</template>

The only thing worth mentioning here is the use of the setAsBackground and truncate filters. In contrast to the uppercase filter we used earlier, they don’t come bundled with Vue and we had to make them ourselves.

Creating Custom Filters

Defining filters is quite easy. The Vue.filter() method provides us with the incoming string data, which we can transform whatever way we want and then simply return.

The first filter we’ll need takes the preview image for a post and creates a CSS rule setting it as background. We use this to set the inline styles with less effort.

It takes one parameter: the URL for the image. If that’s not available a placeholder image is shown instead.

// Filter that takes an image url and creates a CSS style.
Vue.filter('setAsBackground', function(value) {
    if(value && value!='self' && value!='nsfw') {
        return 'background-image: url(' + value + ')';  
    }
    else {
        return 'background-image: url(assets/img/placeholder.png)';   
    }
});

Our other filter takes strings and truncates them if they are too long. This is applied to the post titles, which often are way too lengthy for the design we had in mind.

// Filter for cutting off strings that are too long.
Vue.filter('truncate', function(value) {
    var length = 60;

    if(value.length <= length) {
        return value;
    }
    else {
        return value.substring(0, length) + '...';            
    }
});

The Full Code

Below we’ve listed all of the files for the app, so that you can look through the full code and get a better idea how the whole thing works.

/*-----------------
    Components 
-----------------*/

// Parent | Subreddit component containing a list of 'post' components. 
var subreddit = Vue.component('subreddit',{
    template: '#subreddit',
    props: ['name'],

    data: function () {
        return { posts: [] }
    },

    created: function(){
        this.$http.get("https://www.reddit.com/r/"+ this.name +"/top.json?limit=3")
        .then(function(resp){
            this.posts=resp.data.data.children;
        });
    }
});


// Child | Componenet represiting a single post.
var post = Vue.component('post', {
    template: "#post",
    props: ['item']
});


/*-----------------
   Custom filters 
-----------------*/

// Filter for cutting off strings that are too long.
Vue.filter('truncate', function(value) {
    var length = 60;

    if(value.length <= length) {
        return value;
    }
    else {
        return value.substring(0, length) + '...';            
    }
});


// Filter that takes an image url and creates a CSS style.
Vue.filter('setAsBackground', function(value) {
    if(value && value!='self' && value!='nsfw') {
        return 'background-image: url(' + value + ')';  
    }
    else {
        return 'background-image: url(assets/img/placeholder.png)';   
    }
});


/*-----------------
   Initialize app 
-----------------*/

new Vue({
    el: 'body'
});
<!DOCTYPE html>
<html>
<head>
    <title>Your First App With Vue.js</title>
    <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
    <link rel="stylesheet" type="text/css" href="assets/css/styles.css">
</head>
<body>
    <div class="container">
        <subreddit name="aww"></subreddit>
        <subreddit name="space"></subreddit>
        <subreddit name="gifs"></subreddit>
        <subreddit name="food"></subreddit>
        <subreddit name="comics"></subreddit>
        <subreddit name="sports"></subreddit>
    </div>


    <template id="subreddit">
        <div class="subreddit">
            <h2>{{ name | uppercase }}</h2>
            <ul class="item-list">
                <li v-for="obj in posts">
                    <post :item="obj"></post>
                </li>
            </ul>
        </div>
    </template>

    <template id="post">
        <div class="post">
            <a   :href="item.data.url" :style="item.data.thumbnail | setAsBackground" 
                 target="_blank" class="thumbnail"></a>
            <div class="details">
                <a :href="item.data.url" :title="item.data.title" target="_blank" class="title">
                    {{ item.data.title | truncate}}
                </a>          
                
                <div class="action-buttons">
                    <a href="http://reddit.com{{ item.data.permalink }}" title="Vote">
                        <i class="material-icons">thumbs_up_down</i>
                        {{item.data.score}}
                    </a>

                    <a href="http://reddit.com{{ item.data.permalink }}" title="Go to discussion">
                        <i class="material-icons">forum</i>
                        {{item.data.num_comments}}
                    </a>
                </div>
            </div>
        </div>       
    </template>

    <script src="assets/js/vue.js"></script>
    <script src="assets/js/vue-resource.min.js"></script>
    <script src="assets/js/script.js"></script>
</body>
</html>
*{
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

a{
    text-decoration: none;
}

a:hover{
    text-decoration: underline;
}

html{
    font: normal 16px sans-serif;
    color: #333;
    background-color: #f9f9f9;
}

.container{
    padding: 27px 20px;
    margin: 30px auto 50px;
    max-width: 1250px;
    display: flex;
    flex-wrap: wrap;
    flex-direction: row;
    background-color: #fff;
    box-shadow: 0 0 1px #ccc;
}

/* Subreddit component */

.subreddit{
    flex: 0 0 33%;
    min-width: 400px;
    padding: 20px 42px;
}

.subreddit h2{
    font-size: 18px;
    margin-bottom: 10px;
}

.subreddit .item-list{
    border-top: 1px solid #bec9d0;
    padding-top: 20px;
    list-style: none;
}

.subreddit .item-list li{
    margin-bottom: 17px;
}

/* Post component */

.post{
    display: flex;
}

.post .thumbnail{
    display: block;
    flex: 0 0 60px;
    height: 60px;
    background-repeat: no-repeat;
    background-size: cover;
    background-position: center;
    margin-right: 10px;
    border-radius: 4px;
    margin-right: 12px;
}

.post .details{
    display: flex;
    flex-direction: column;
}

.post .details .title{
    font-size: 15px;
    margin-bottom: 3px;
    color: #04477b;
}

.post .details .title:visited{
    color: purple;
}

.post .details .action-buttons a{
    font-size: 11px;
    margin-right: 4px;
    display: inline-block;
    color: #666;
}

.post .details .action-buttons i{
    font-size: 10px;
    margin-right: 1px;
}

@media(max-width: 1250px){

    .container{
        justify-content: center;
        margin: 30px 30px 50px 30px;
    }
}

@media(max-width: 500px){

    .subreddit{
        min-width: 300px;
        padding: 20px 15px;
    }
}

Note that after creating our two components, the entire app interface comes down to:

<div class="container">
    <subreddit name="aww"></subreddit>
    <subreddit name="space"></subreddit>
    <subreddit name="gifs"></subreddit>
    <subreddit name="food"></subreddit>
    <subreddit name="comics"></subreddit>
    <subreddit name="sports"></subreddit>
</div>

The JavaScript file isn’t too large either and this is one of my favorite things about Vue. It does so much of the work for us that in the end we are left with a very clean and comprehensive piece of code.

Further Reading

The main focus of this tutorial was to show the process of building a simple Vue.js app. To keep it short we haven’t stopped to explain every tiny syntax peculiarity, but worry not! There are many awesome resources where you can learn the basics:

This concludes our Vue.js tutorial! We hope that you’ve had lots of fun with it and that you’ve learned a thing or two. If you have any suggestions or questions, feel free to leave a message in the comment section below :)

Tags: , , , ,
Posted in PHP Tutorials | Comments Off on Building Your First App With Vue.js

Take a Selfie With JavaScript

Monday, July 25th, 2016

take-a-selfie-with-js

In this tutorial we are going to show you how to make a JavaScript photobooth app that takes images using the camera on your phone, laptop or desktop. We will showcase a number of awesome native APIs that allowed us to make our project without any external dependencies, third-party libraries or Flash – vanilla JavaScript only!

Note that this app uses experimental technologies that are not available in desktop and mobile Safari.

The App

To the end user our app is just an oversimplified version of the camera app you can find on any smartphone. It uses a hardware camera to take pictures – that’s it. Under the hood, however, a whole lot of JavaScript magic is going on. Here is a high-level overview:

  1. We access the camera input and get a video stream from it using the getUserMedia API.
  2. Project the camera stream onto a HTML video element.
  3. When the user wants to take a picture, we copy the current video frame and draw it on a canvas element.
  4. Transform the canvas into an image dataURL which then can be shown on the screen or downloaded as a PNG.

In the article below we will only look at the more interesting parts of the code. For the full source go to the Download button near the top of this page or checkout the demo on JSfiddle.

Keep in mind that the navigator.getUserMedia API is considered deprecated, but it still has pretty good browser support and is the only way to access the camera right now, until it’s future replacement – navigator.mediaDevices.getUserMedia gains wider browser support.

Demo on JSfiddle

Demo on JSfiddle

Accessing The Camera

JavaScript provides a native API for accessing any camera hardware in the form of the navigator.getUserMedia method. Since it handles private data this API work only in secure HTTPS connections and always asks for user permission before proceeding.

camera-permission

Permission Dialog In Desktop Chrome

If the user allows to enable his camera, navigator.getUserMedia gives us a video stream in a success callback. This stream consists of the raw broadcast data coming in from the camera and needs to be transformed into an actual usable media source with the createObjectURL method.

navigator.getUserMedia(
    // Options
    {
        video: true
    },
    // Success Callback
    function(stream){

        // Create an object URL for the video stream and
        // set it as src of our HTLM video element.
        video.src = window.URL.createObjectURL(stream);

        // Play the video element to show the stream to the user.
        video.play();
 
    },
    // Error Callback
    function(err){

        // Most common errors are PermissionDenied and DevicesNotFound.
        console.error(err);

    }
);

Taking a Still Photo

Once we have the video stream going, we can take snapshots from the camera input. This is done with a nifty trick that utilizes the mighty <canvas> element to grab a frame from the running video stream and save it in an <img> element.

function takeSnapshot(){

    var hidden_canvas = document.querySelector('canvas'),
        video = document.querySelector('video.camera_stream'),
        image = document.querySelector('img.photo'),

        // Get the exact size of the video element.
        width = video.videoWidth,
        height = video.videoHeight,

        // Context object for working with the canvas.
        context = hidden_canvas.getContext('2d');


    // Set the canvas to the same dimensions as the video.
    hidden_canvas.width = width;
    hidden_canvas.height = height;

    // Draw a copy of the current frame from the video on the canvas.
    context.drawImage(video, 0, 0, width, height);

    // Get an image dataURL from the canvas.
    var imageDataURL = hidden_canvas.toDataURL('image/png');

    // Set the dataURL as source of an image element, showing the captured photo.
    image.setAttribute('src', imageDataURL); 

}

The canvas element itself doesn’t even need to be visible in the DOM. We are only using its JavaScript API as a way to capture a still moment from the video.

Downloading The Photo

Of course, we not only want to take glorious selfies but we also want be able to save them for future generations to see. The easiest way to do this is with the download attribute for <a> elements. In the HTML the button looks like this:

<a id="dl-btn" href="#" download="glorious_selfie.png">Save Photo</a>

The download attribute transforms our anchor from a hyperlink into a download button. Its value represents the default name of the downloadable file, the actual file to download is stored in the href attribute, which as you can see is empty for now. To load our newly taken photo here, we can use the image dataURL from the previous section:

function takeSnapshot(){

    //...

    // Get an image dataURL from the canvas.
    var imageDataURL = hidden_canvas.toDataURL('image/png');

    // Set the href attribute of the download button.
    document.querySelector('#dl-btn').href = imageDataURL;
}

Now when somebody clicks on that button they will be prompted to download a file named glorious_selfie.png, containing the photo they took. With this our little experiment is complete!

Conclusion

We hope that you’ve learned a lot from this tutorial and that you now feel inspired to build some kick-ass photo apps. As always, feel free to ask questions or share ideas in the comment section below!

Tags: , , , ,
Posted in PHP Tutorials | Comments Off on Take a Selfie With JavaScript

Learn TypeScript in 30 Minutes

Tuesday, July 19th, 2016

learn-typescript-in-30

Today we’re going to take a look at TypeScript, a compile-to-JavaScript language designed for developers who build large and complex apps. It inherits many programming concepts from languages such as C# and Java that add more discipline and order to the otherwise very relaxed and free-typed JavaScript.

This tutorial is aimed at people who are fairly proficient in JavaScript but are still beginners when it comes to TypeScript. We’ve covered most of the basics and key features while including lots of examples with commented code to help you see the language in action. Let’s begin!


The Benefits of Using TypeScript

JavaScript is pretty good as it is and you may wonder Do I really need to learn TypeScript? Technically, you do not need to learn TypeScript to be a good developer, most people do just fine without it. However, working with TypeScript definitely has its benefits:

The last point is actually the most important to many people and is the main reason to get them into TypeScript. Angular 2 is one of the hottest frameworks right now and although developers can use regular JavaScript with it, a majority of the tutorials and examples are written in TS. As Angular 2 expands its community, it’s natural that more and more people will be picking up TypeScript.

tscript-trend

Recent rise of TypeScript’s popularity, data from Google Trends.


1_Installation

Installing TypeScript

You will need Node.js and Npm for this tutorial. Go here if you don’t have them installed.

The easiest way to setup TypeScript is via npm. Using the command below we can install the TypeScript package globally, making the TS compiler available in all of our projects:

npm install -g typescript

Try opening a terminal anywhere and running tsc -v to see if it has been properly installed.

tsc -v
Version 1.8.10

2_text_editors

Text Editors With TypeScript Support

TypeScript is an open-source project but is developed and maintained by Microsoft and as such was originally supported only in Microsoft’s Visual Studio platform. Nowadays, there are a lot more text editors and IDEs that either natively or through plugins offer support for the TypeScript syntax, auto-complete suggestions, error catching, and even built-in compilers.


Compiling to JavaScript

TypeScript is written in .ts files (or .tsx for JSX), which can’t be used directly in the browser and need to be translated to vanilla .js first. This compilation process can be done in a number of different ways:

We found the first way to be easiest and most beginner friendly, so that’s what we’re going to use in our lesson.

The following command takes a TypeScript file named main.ts and translates it into its JavaScript version main.js. If main.js already exists it will be overwritten.

tsc main.ts

We can also compile multiple files at once by listing all of them or by applying wildcards:

# Will result in separate .js files: main.js worker.js.
tsc main.ts worker.ts    

# Compiles all .ts files in the current folder. Does NOT work recursively.
tsc *.ts

We can also use the --watch option to automatically compile a TypeScript file when changes are made:

# Initializes a watcher process that will keep main.js up to date.
tsc main.ts --watch

More advanced TypeScript users can also create a tsconfig.json file, consisting of various build settings. A configuration file is very handy when working on large projects with lots of .ts files since it somewhat automates the process. You can read more about tsconfig.json in the TypeScript docs here


Static Typing

A very distinctive feature of TypeScript is the support of static typing. This means that you can declare the types of variables, and the compiler will make sure that they aren’t assigned the wrong types of values. If type declarations are omitted, they will be inferred automatically from your code.

Here is an example. Any variable, function argument or return value can have its type defined on initialization:

var burger: string = 'hamburger',     // String 
    calories: number = 300,           // Numeric
    tasty: boolean = true;            // Boolean

// Alternatively, you can omit the type declaration:
// var burger = 'hamburger';

// The function expects a string and an integer.
// It doesn't return anything so the type of the function itself is void.

function speak(food: string, energy: number): void {
  console.log("Our " + food + " has " + energy + " calories.");
}

speak(burger, calories);

Because TypeScript is compiled to JavaScript, and the latter has no idea what types are, they are completely removed:

// JavaScript code from the above TS example.

var burger = 'hamburger',
    calories = 300, 
    tasty = true; 

function speak(food, energy) {
    console.log("Our " + food + " has " + energy + " calories.");
}

speak(burger, calories);

However, if we try to do something illegal, on compilation tsc will warn us that there is an error in our code. For example:

// The given type is boolean, the provided value is a string.
var tasty: boolean = "I haven't tried it yet";
main.ts(1,5): error TS2322: Type 'string' is not assignable to type 'boolean'.

It will also warn us if we pass the wrong argument to a function:

function speak(food: string, energy: number): void{
  console.log("Our " + food + " has " + energy + " calories.");
}

// Arguments don't match the function parameters.
speak("tripple cheesburger", "a ton of");
main.ts(5,30): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.

Here are some of the most commonly used data types:

To see a list of all of the available types, go to the official TypeScript docs – here.


5_interfaces

Interfaces

Interfaces are used to type-check whether an object fits a certain structure. By defining an interface we can name a specific combination of variables, making sure that they will always go together. When translated to JavaScript, interfaces disappear – their only purpose is to help in the development stage.

In the below example we define a simple interface to type-check a function’s arguments:

// Here we define our Food interface, its properties, and their types.
interface Food {
    name: string;
    calories: number;
}

// We tell our function to expect an object that fulfills the Food interface. 
// This way we know that the properties we need will always be available.
function speak(food: Food): void{
  console.log("Our " + food.name + " has " + food.calories + " calories.");
}

// We define an object that has all of the properties the Food interface expects.
// Notice that types will be inferred automatically.
var ice_cream = {
  name: "ice cream", 
  calories: 200
}

speak(ice_cream);

The order of the properties does NOT matter. We just need the required properties to be present and to be the right type. If something is missing, has the wrong type, or is named differently, the compiler will warn us.

interface Food {
    name: string;
    calories: number;
}

function speak(food: Food): void{
  console.log("Our " + food.name + " has " + food.calories + " grams.");
}

// We've made a deliberate mistake and name is misspelled as nmae.
var ice_cream = {
  nmae: "ice cream", 
  calories: 200
}

speak(ice_cream);
main.ts(16,7): error TS2345: Argument of type '{ nmae: string; calories: number; } 
is not assignable to parameter of type 'Food'. 
Property 'name' is missing in type '{ nmae: string; calories: number; }'.

This is a beginners guide so we won’t be going into more detail about interfaces. However, there is a lot more to them than what we’ve mentioned here so we recommend you check out the TypeScript docs – here.


6_classes

Classes

When building large scale apps, the object oriented style of programming is preferred by many developers, most notably in languages such as Java or C#. TypeScript offers a class system that is very similar to the one in these languages, including inheritance, abstract classes, interface implementations, setters/getters, and more.

It’s also fair to mention that since the most recent JavaScript update (ECMAScript 2015), classes are native to vanilla JS and can be used without TypeScript. The two implementation are very similar but have their differences, TypeScript being a bit more strict.

Continuing with the food theme, here is a simple TypeScript class:

class Menu {
  // Our properties:
  // By default they are public, but can also be private or protected.
  items: Array<string>;  // The items in the menu, an array of strings.
  pages: number;         // How many pages will the menu be, a number.

  // A straightforward constructor. 
  constructor(item_list: Array<string>, total_pages: number) {
    // The this keyword is mandatory.
    this.items = item_list;    
    this.pages = total_pages;
  }

  // Methods
  list(): void {
    console.log("Our menu for today:");
    for(var i=0; i<this.items.length; i++) {
      console.log(this.items[i]);
    }
  }

} 

// Create a new instance of the Menu class.
var sundayMenu = new Menu(["pancakes","waffles","orange juice"], 1);

// Call the list method.
sundayMenu.list();

Anyone who has written at least a bit of Java or C# should find this syntax comfortably familiar. The same goes for inheritance:

class HappyMeal extends Menu {
  // Properties are inherited

  // A new constructor has to be defined.
  constructor(item_list: Array<string>, total_pages: number) {
    // In this case we want the exact same constructor as the parent class (Menu), 
    // To automatically copy it we can call super() - a reference to the parent's constructor.
    super(item_list, total_pages);
  }

  // Just like the properties, methods are inherited from the parent.
  // However, we want to override the list() function so we redefine it.
  list(): void{
    console.log("Our special menu for children:");
    for(var i=0; i<this.items.length; i++) {
      console.log(this.items[i]);
    }

  }
}

// Create a new instance of the HappyMeal class.
var menu_for_children = new HappyMeal(["candy","drink","toy"], 1);

// This time the log message will begin with the special introduction.
menu_for_children.list();

For a more in-depth look at classes in TS you can read the documentation – here.


7_generics

Generics

Generics are templates that allow the same function to accept arguments of various different types. Creating reusable components using generics is better than using the any data type, as generics preserve the types of the variables that go in and out of them.

A quick example would be a script that receives an argument and returns an array containing that same argument.

// The <T> after the function name symbolizes that it's a generic function.
// When we call the function, every instance of T will be replaced with the actual provided type.

// Receives one argument of type T,
// Returns an array of type T.

function genericFunc<T>(argument: T): T[] {    
  var arrayOfT: T[] = [];    // Create empty array of type T.
  arrayOfT.push(argument);   // Push, now arrayOfT = [argument].
  return arrayOfT;
}

var arrayFromString = genericFunc<string>("beep");
console.log(arrayFromString[0]);         // "beep"
console.log(typeof arrayFromString[0])   // String

var arrayFromNumber = genericFunc(42);
console.log(arrayFromNumber[0]);         // 42
console.log(typeof arrayFromNumber[0])   // number

The first time we called the function we manually set the type to string. This isn’t required as the compiler can see what argument has been passed and automatically decide what type suits it best, like in the second call. Although it’s not mandatory, providing the type every time is considered good practice as the compiler might fail to guess the right type in more complex scenarios.

The TypeScript docs include a couple of advanced examples including generics classes, combining them with interfaces, and more. You can find them here.


8_modules

Modules

Another important concept when working on large apps is modularity. Having your code split into many small reusable components helps your project stay organized and understandable, compared to having a single 10000-line file for everything.

TypeScript introduces a syntax for exporting and importing modules, but cannot handle the actual wiring between files. To enable external modules TS relies on third-party libraries: require.js for browser apps and CommonJS for Node.js. Let’s take a look at a simple example of TypeScript modules with require.js:

We will have two files. One exports a function, the other imports and calls it.

exporter.ts

var sayHi = function(): void {
    console.log("Hello!");
}

export = sayHi;

importer.ts

import sayHi = require('./exporter');
sayHi();

Now we need to download require.js and include it in a script tag – see how here. The last step is to compile our two .ts files. An extra parameter needs to be added to tell TypeScript that we are building modules for require.js (also referred to as AMD), as opposed to CommonJS ones.

tsc --module amd *.ts

Modules are quite complex and are out of the scope of this tutorial. If you want to continue reading about them head out to the TS docs – here.


9_declaration_files

Third-party Declaration Files

When using a library that was originally designed for regular JavaScript, we need to apply a declaration file to make that library compatible with TypeScript. A declaration file has the extension .d.ts and contains various information about the library and its API.

TypeScript declaration files are usually written by hand, but there’s a high chance that the library you need already has a .d.ts. file created by somebody else. DefinitelyTyped is the biggest public repository, containing files for over a thousand libraries. There is also a popular Node.js module for managing TypeScript definitions called Typings.

If you still need to write a declaration file yourself, this guide will get you started.


10_typescript_2

Upcoming Features in TypeScript 2.0

TypeScript is still under active development and is evlolving constantly. At the time of the writing of this tutorial the LTS version is 1.8.10, but Microsoft have already released a Beta for TypeScript 2.0. It’s available for public testing and you can try it out now:

npm install -g typescript@beta

It introduces some handy new concepts such as:

Another long-awaited feature is the ability to control the flow of asynchronous functions in an async/await block. This should be available in a future 2.1 update.

Further Reading

The amount of information in the official docs can be a bit overwhelming at first, but the benefits of going through it will be huge. Our tutorial is to be used as an introduction, so we haven’t covered all of the chapters from the TypeScript documentation. Here are some of the more useful concepts that we’ve skipped:

Conclusion

We hope you enjoyed this tutorial!

Do you have any thoughts on TypeScript and would you consider using it in your projects? Feel free to leave a comment below!

Tags: , , , ,
Posted in PHP Tutorials | Comments Off on Learn TypeScript in 30 Minutes

Quick Tip: Detecting Your Location With JavaScript

Wednesday, June 22nd, 2016

learn-git-in-30-minutes

Most modern devices are capable of detecting their own location either through GPS, WiFi, or IP geolocation. Developers can use this information to provide better search suggestions, nearby store locations, and implement all kinds of useful map interactions in their apps and websites.

In the article below we’re going to take a look at an easy, pure-JavaScript way to access a device’s whereabouts without relying on any external dependencies or third-party services. Let’s begin!

Location sources

JavaScript offers a simple, yet powerful tool for locating devices in the form of the Geolocation API. It consists of a small set of easy to use methods that can obtain the device position through all three of the previously mentioned services:

When geo data is requested the browser will try and use all three of the above options depending on what’s available. The results from the WiFi source are usually used as it is quicker than GPS and way more accurate than IP geolcation.

Using the Geolocation API

The Geolocation API has almost full cross-browser support, but to make sure that it’s accessible to our users, it’s a good idea before doing anything to check whether the geolocation object exists in the Window.navigator interface.

if (navigator.geolocation) {
  // geolocation is available
} 
else {
  // geolocation is not supported
}

Inside the navigator.geolocation object reside all of the methods for the API:

Тhe getCurrentPosition() and watchPosition() methods are used in a nearly identical fashion. They both work asynchronously, trying to obtain the device position and depending on the outcome of the attempt call a success callback or an error callback if it’s provided.

navigator.geolocation.getCurrentPosition(

    // Success callback
    function(position) {

        /*
        position is an object containing various information about
        the acquired device location:

        position = {
            coords: {
                latitude - Geographical latitude in decimal degrees.
                latitude - Geographical longitude in decimal degrees. 
                altitude - Height in meters relative to sea level.
                accuracy - Possible error margin for the coordinates in meters. 
                altitudeAccuracy - Possible error margin for the altitude in meters. 
                heading - The direction of the device in degrees relative to north. 
                speed - The velocity of the device in meters per second.
            }
            timestamp - The time at which the location was retrieved.
        }
        */

    },

    // Optional error callback
    function(error){

        /* 
        In the error object is stored the reason for the failed attempt:

        error = {
            code - Error code representing the type of error 
                    1 - PERMISSION_DENIED
                    2 - POSITION_UNAVAILABLE
                    3 - TIMEOUT

            message - Details about the error in human-readable format.
        }
        */

    }
);

As you can see, using the Geolocation API is pretty straightforward. We just have to call the right method, wait for it to return the coordinates, and then do whatever we want with them.

User permission

Since the Geolocation API exposes deeply personal information, when an application tries to access it for the first time, a dialog pops up requesting permission. This ensures that users will not have their private data revealed unless they explicitly allow it.

Permission Dialog In Desktop Chrome

Permission Dialog In Chrome On Android

Permission Dialog In Chrome On Android

The browser usually takes care for displaying the dialog, but permission can also be requested programmatically by the developer. This is sometimes necessary, since once denied the original browser-generated dialog doesn’t show itself a second time.

Secure hosts

Another protective measure is the usage of an HTTPS connection. Due to a new web security policy, Google Chrome (both desktop and mobile versions) no longer allows non-secure hosts to run the Geolocation API. Instead, developers who want to use this feature are required to serve their apps over HTTPS, thus minimizing the risks of having people’s data stolen or abused.

You can read more about the issue in this Google Developers blog post.

Demo app

To demonstrate how the whole process works, we’ve built an oversimplified app showcasing some of the capabilities of the API. It consists of a button, which when pressed, grabs the device coordinates and feeds them to this GMaps plugin, pinpointing the location on the map.

findMeButton.on('click', function(){

    navigator.geolocation.getCurrentPosition(function(position) {

        // Get the coordinates of the current position.
        var lat = position.coords.latitude;
        var lng = position.coords.longitude;

        // Create a new map and place a marker at the device location.
        var map = new GMaps({
            el: '#map',
            lat: lat,
            lng: lng
        });

        map.addMarker({
            lat: lat,
            lng: lng
        });

    });
    
});

The demo, as well as the full code are available on JSFiddle:

Demo on JSfiddle

Demo on JSfiddle

Conclusion

The Gelocation API is reliable and production ready, so we encourage you to play around with it and see what it’s capable of. If you’ve seen some original uses of this technology on the web, or you’ve made a cool project yourself, fell free to share it in the comment section below – we would love to see it!

Tags: , , , ,
Posted in PHP Tutorials | Comments Off on Quick Tip: Detecting Your Location With JavaScript

Learn Git in 30 Minutes

Thursday, June 2nd, 2016

learn-git-in-30-minutes

Git has exploded in popularity in recent years. The verison control system is used by huge open source projects like Linux with thousands of contributors, teams of various sizes, solo developers and even students.

Beginners are often terrified by all the cryptic commands and arguments that git requires. But you don’t need to know all of that to get started. You can begin by mastering a handful of the most often used ones, and then slowly build from there. And this is exactly what we will teach you today. Let’s begin!


basics

The basics

Git is a collection of command line utilities that track and record changes in files (most often source code, but you can track anything you wish). With it you can restore old versions of your project, compare, analyze, merge changes and more. This process is referred to as version control. There are a number of version control systems that do this job. You may have heard some of them – SVN, Marcurial, Perforce, CVS, Bitkeeper and more.

Git is decentralized, which means that it doesn’t depend on a central server to keep old versions of your files. Instead it works fully locally by storing this data as a folder on your hard drive, which we call a repository. However you can store a copy of your repository online, which makes it easy for multiple people to collaborate and work on the same code. This is what websites like GitHub and BitBucket are used for.

1. Installing Git

Installing Git on your machine is straightforward:

If you are an absolute beginner, then a graphical git client is a must. We recommend GitHub Desktop and Sourcetree, but there are many other good and free ones online. Getting to know the basic git commands is still important even if you use a GUI app, so for the remaining of this lesson, this will be our only focus.

2. Configuring Git

Now that we’ve installed git on our computer, we will need to add some quick configurations. There are a lot of options that can be fiddled with, but we are going to set up the most important ones: our username and email. Open a terminal and run these commands:

$ git config --global user.name "My Name"
$ git config --global user.email myEmail@example.com

Every action we do in Git will now have a stamp with our name and address on it. This way users always know who did what and everything is way more organized.

3. Creating a new repository – git init

As we mentioned earlier, git stores its files and history directly as a folder in your project. To set up a new repository, we need to open a terminal, navigate to our project directory and run git init. This will enable Git for this particular folder and create a hidden .git directory where the repository history and configuration will be stored.

Create a folder on your Desktop called git_exercise, open a new terminal and enter the following:

$ cd Desktop/git_exercise/
$ git init

The command line should respond with something along the lines of:

Initialized empty Git repository in /home/user/Desktop/git_exercise/.git/

This means that our repo has been successfully created but is still empty. Now create a simple text file called hello.txt and save it in the git_exercise folder.

4. Checking the status – git status

Git status is another must-know command that returns information about the current state of the repository: is everything up to date, what’s new, what’s changed, and so on. Running git status in our newly created repo should return the following:

$ git status

On branch master

Initial commit

Untracked files:
  (use "git add ..." to include in what will be committed)

	hello.txt

The returned message states that hello.txt is untracked. This means that the file is new and Git doesn’t know yet if it should keep track of the changes happening to that file or just ignore it. To acknowledge the new file, we need to stage it.

5. Staging – git add

Git has the concept of a “staging area”. You can think of this like a blank canvas, which holds the changes which you would like to commit. It starts out empty, but you can add files to it (or even single lines and parts of files) with the git add command, and finally commit everything (create a snapshot) with git commit.

In our case we have only one file so let’s add that:

$ git add hello.txt

If we want to add everything in the directory, we can use:

$ git add -A

Checking the status again should return a different response from before.

$ git status

On branch master

Initial commit

Changes to be committed:
  (use "git rm --cached ..." to unstage)

	new file:   hello.txt

Our file is ready to be commited. The status message also tells us what has changed about the files in the staging area – in this case its new file, but it can be modified or deleted, depending on what has happened to a file since the last git add.

6. Commiting – git commit

A commit represents the state of our repository at a given point in time. It’s like a snapshot, which we can go back to and see how thing were when we took it.

To create a new commit we need to have at least one change added to the staging area (we just did that with git add) and run the following:

$ git commit -m "Initial commit."

This will create a new commit with all the changes from the staging area (adding hello.txt). The -m "Initial commmit" part is a custom user-written description that summarizes the changes done in that commit. It is considered a good practice to commit often and always write meaningful commit messages.


remotes

Remote repositories

Right now our commit is local – it exist only in the .git folder. Although a local repository is useful by itself, in most cases we will want to share our work and deploy it to a server or a repository hosting service.

1. Connecting to a remote repository – git remote add

In order to upload something to a remote repo, we first have to establish a connection with it. For the sake of this tutorial our repository’s address will be https://github.com/tutorialzine/awesome-project. We advise you to go ahead and create your own empty repository at GitHub, BitBucket or any other service. The registration and setup may take a while, but all services offer good step-by-step guides to help you.

To link our local repository with the one on GitHub, we execute the following line in the terminal:

# This is only an example. Replace the URI with your own repository address.
$ git remote add origin https://github.com/tutorialzine/awesome-project.git

A project may have many remote repositories at the same time. To be able to tell them apart we give them different names. Traditionally the main remote repository in git is called origin.

2. Uploading to a server – git push

Now it’s time to transfer our local commits to the server. This process is called a push, and is done every time we want to update the remote repository.

The Git command to do this is git push and takes two parameters – the name of the remote repo (we called ours origin) and the branch to push to (master is the default branch for every repo).

$ git push origin master

Counting objects: 3, done.
Writing objects: 100% (3/3), 212 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To https://github.com/tutorialzine/awesome-project.git
 * [new branch]      master -> master

Depending on the service you’re using, you will need to authenticate yourself for the push to go through. If everything was done correctly, when you go in your web browser to the remote repository created earlier, hello.txt should be available there.

3. Cloning a repository – git clone

At this point, people can see and browse through your remote repository on Github. They can download it locally and have a fully working copy of your project with the git clone command:

$ git clone https://github.com/tutorialzine/awesome-project.git

A new local respository is automatically created, with the github version configured as a remote.

4. Getting changes from a server – git pull

If you make updates to your repository, people can download your changes with a single command – pull:

$ git pull origin master

From https://github.com/tutorialzine/awesome-project
 * branch            master     -> FETCH_HEAD
Already up-to-date.

Since nobody else has commited since we cloned, there weren’t any changes to download.


Branches

When developing a new feature, it is considered a good practice to work on a copy of the original project, called a branch. Branches have their own history and isolate their changes from one another, until you decide to merge them back together. This is done for a couple of reasons:

1. Creating new branches – git branch

The default branch of every repository is called master. To create additional branches use the git branch <name> command:

$ git branch amazing_new_feature

This just creates the new branch, which at this point is exactly the same as our master.

2. Switching branches – git checkout

Now, when we run git branch,  we will see there are two options available:

$ git branch
  amazing_new_feature
* master

Master is the current branch and is marked with an asterisk. However, we want to work on our new amazing features, so we need to switch to the other branch. This is done with the git checkout command, expecting one parameter – the branch to switch to.

$ git checkout amazing_new_feature

3. Merging branches – git merge

Our “amazing new feature” is going to be just another text file called feature.txt. We will create it, add it, and commit it.

$ git add feature.txt
$ git commit -m "New feature complete."

The new feature is complete, we can go back to the master branch.

$ git checkout master

Now, if we open our project in the file browser, we’ll notice that feature.txt has disappeared. That’s because we are back in the master branch, and here feature.txt was never created. To bring it in, we need to git merge the two branches together, applying the changes done in amazing_new_feature to the main version of the project.

git merge amazing_new_feature

The master branch is now up to date. The awesome_new_feature branch is no longer needed and can be removed.

git branch -d awesome_new_feature

 advanced

Advanced

In the last section of this tutorial, we are going to take a look at some more advanced techniques that are very likely to come in handy.

1. Checking difference between commits

Every commit has it’s unique id in the form of a string of numbers and symbols. To see a list of all commits and their ids we can use git log:

$ git log

commit ba25c0ff30e1b2f0259157b42b9f8f5d174d80d7
Author: Tutorialzine
Date:   Mon May 30 17:15:28 2016 +0300

    New feature complete

commit b10cc1238e355c02a044ef9f9860811ff605c9b4
Author: Tutorialzine
Date:   Mon May 30 16:30:04 2016 +0300

    Added content to hello.txt

commit 09bd8cc171d7084e78e4d118a2346b7487dca059
Author: Tutorialzine
Date:   Sat May 28 17:52:14 2016 +0300

    Initial commit

As you can see the ids are really long, but when working with them it’s not necessary to copy the whole thing – the first several symbols are usually enough.
To see what was new in a commit we can run git show [commit]:

$ git show b10cc123

commit b10cc1238e355c02a044ef9f9860811ff605c9b4
Author: Tutorialzine
Date:   Mon May 30 16:30:04 2016 +0300

    Added content to hello.txt

diff --git a/hello.txt b/hello.txt
index e69de29..b546a21 100644
--- a/hello.txt
+++ b/hello.txt
@@ -0,0 +1 @@
+Nice weather today, isn't it?

To see the difference between any two commits we can use git diff with the [commit-from]..[commit-to] syntax:

$ git diff 09bd8cc..ba25c0ff

diff --git a/feature.txt b/feature.txt
new file mode 100644
index 0000000..e69de29
diff --git a/hello.txt b/hello.txt
index e69de29..b546a21 100644
--- a/hello.txt
+++ b/hello.txt
@@ -0,0 +1 @@
+Nice weather today, isn't it?

We’ve compared the first commit to the last one, so we see all the changes that have ever been made.

2. Fixing a commit

If you notice that you’ve made a typo in your commit message, or you’ve forgotten to add a file and you see right after you commit, you can easily fix this with git commit --amend.  This will add everything from the last commit back to the staging area, and attempt to make a new commit. This gives you a chance to fix your commit message or add more files to the staging area.

For more complex fixes that aren’t in the last commit (or if you’ve pushed your changes already), you’ve got to use git revert. This will take all the changes that a commit has introduced, reverse them, and create a new commit that is the exact opposite.

The newest commit can be accessed by the HEAD alias.

$ git revert HEAD

For other commits it’s best to use an id.

$ git revert b10cc123

When reverting older commits, keep in mind that merge conflicts are very likely to appear. This happens when a file has been altered by another more recent commit, and now Git cannot find the right lines to revert, since they aren’t there anymore.

3. Resolving Merge Conflicts

Apart from the scenario depicted in the previous point, conflicts regularly appear when merging branches or pulling someone else’s work. Sometimes conflicts are handled automatically by git, but other times the person dealing with them has to decide (and usually handpick) what code stays and what is removed.

Let’s look at an example where we’re trying to merge two branches called john_branch and tim_branch. Both John and Tim are writing in the same file a function that displays all the elements in an array.

John is using a for loop:

// Use a for loop to console.log contents.
for(var i=0; i<arr.length; i++) {
    console.log(arr[i]);
}

Tim prefers forEach:

// Use forEach to console.log contents.
arr.forEach(function(item) {
    console.log(item);
});

They both commit their code on their respective branch. Now if they try to merge the two branches they will see the following error message:

$ git merge tim_branch 

Auto-merging print_array.js
CONFLICT (content): Merge conflict in print_array.js
Automatic merge failed; fix conflicts and then commit the result.

Git wasn’t able to merge the branches automatically, so now it’s up to the devs to manually resolve the conflict. If they open the file where the conflict resides, they’ll see that Git has inserted a marker on the conflicting lines.

<<<<<<< HEAD
// Use a for loop to console.log contents.
for(var i=0; i<arr.length; i++) {
    console.log(arr[i]);
}
=======
// Use forEach to console.log contents.
arr.forEach(function(item) {
    console.log(item);
});
>>>>>>> Tim's commit.

Above the ===== we have the current HEAD commit, and below the conflicting one. This way we can clearly see the differences, and decide which is the better version, or write a new one all together. In this situation we go for the latter and rewrite the whole thing, removing the markers to let Git know we’re done.

// Not using for loop or forEach.
// Use Array.toString() to console.log contents.
console.log(arr.toString());

When everything is set, a merge commit has to be done to finish the process.

$ git add -A
$ git commit -m "Array printing conflict resolved."

As you can see this process is quite tiresome and can get extremely hard to deal with in large projects. Most developers prefer to resolve conflicts with the help of a GUI client, which makes things much easier.

4. Setting up .gitignore

In most projects there are files or entire folders that we don’t want to ever commit. We can make sure that they aren’t accidentally included in our git add -A by creating a .gitignore file:

  1. Manually create a text file called .gitignore and save it in your project’s directory.
  2. Inside, list the names of files/directories to be ignored, each on a new line.
  3. The .gitignore itself has to be added, committed and pushed, as it is just like any other file in the project.

Good examples for files to be ignored are:

A .gitignore banning all of the above will look like this:

*.log
build/
node_modules/
.idea/
my_notes.txt

The slash at the end of some of the lines signals that this is a folder and we are ignoring everything inside it recursively. The asterisk serves it’s usual function as a wild card.


Conclusion

This ends our tutorial on git! We tried our best to bring you only the most important information you need, presented as short and concise as possible.

Git is quite complex and has a lot more features and tricks to offer. If you wish to find out more, here are some learning resources we recommend:

Tags: , , , ,
Posted in PHP Tutorials | Comments Off on Learn Git in 30 Minutes