Tuesday, January 16, 2018

How to Build a File Upload Form with Express and Dropzone.js

Let’s face it, nobody likes forms. Developers don’t like building them, designers don’t particularly enjoy styling them and users certainly don’t like filling them in.

Of all the components that can make up a form, the file control could just be the most frustrating of the lot. A real pain to style, clunky and awkward to use and uploading a file will slow down the submission process of any form.

That’s why a plugin to enhance them is always worth a look, and DropzoneJS is just one such option. It will make your file upload controls look better, make them more user-friendly and by using AJAX to upload the file in the background, at the very least make the process seem quicker. It also makes it easier to validate files before they even reach your server, providing near-instananeous feedback to the user.

We’re going to take a look at DropzoneJS in some detail; show how to implement it and look at some of the ways in which it can be tweaked and customized. We’ll also implement a simple server-side upload mechanism using Node.js.

As ever, you can find the code for this tutorial on our GitHub repository.

Introducing DropzoneJS

As the name implies, DropzoneJS allows users to upload files using drag n’ drop. Whilst the usability benefits could justifiably be debated, it’s an increasingly common approach and one which is in tune with the way a lot of people work with files on their desktop. It’s also pretty well supported across major browsers.

DropzoneJS isn’t simply a drag n’drop based widget, however; clicking the widget launches the more conventional file chooser dialog approach.

Here’s an animation of the widget in action:

The DropzoneJS widget in action

Alternatively, take a look at this, most minimal of examples.

You can use DropzoneJS for any type of file, though the nice little thumbnail effect makes it ideally suited to uploading images in particular.

Features

To summarize some of the plugin’s features and characteristics:

  • Can be used with or without jQuery
  • Drag and drop support
  • Generates thumbnail images
  • Supports multiple uploads, optionally in parallel
  • Includes a progress bar
  • Fully themeable
  • Extensible file validation support
  • Available as an AMD module or RequireJS module
  • It comes in at around 33Kb when minified

Browser Support

Taken from the official documentation, browser support is as follows:

  • Chrome 7+
  • Firefox 4+
  • IE 10+
  • Opera 12+ (Version 12 for MacOS is disabled because their API is buggy)
  • Safari 6+

There are a couple of ways to handle fallbacks for when the plugin isn’t fully supported, which we’ll look at later.

Installation

The simplest way to install DropzoneJS is via Bower:

bower install dropzone

Alternatively you can grab it from Github, or simply download the standalone JavaScript file — though bear in mind you’ll also need the basic styles, also available in the Github repo.

There are also third-party packages providing support for ReactJS and implementing the widget as an Angular directive.

First Steps

If you’ve used the Bower or download method, make sure you include both the main JS file and the styles (or include them into your application’s stylesheet), e.g:

<link rel="stylesheet" href="/path/to/dropzone.css">
<script type="text/javascript" src="/path/to/dropzone.js"></script>

Pre-minified versions are also supplied in the package.

Tip: If you’re using RequireJS, use dropzone-amd-module.js instead.

Basic Usage

The simplest way to implement the plugin is to attach it to a form, although you can use any HTML such as a div tag. Using a form, however, means less options to set — most notably the URL, which is the most important configuration property.

You can initialize it simply by adding the dropzone class, for example:

<form id="upload-widget" method="post" action="/upload" class="dropzone">
</form>

Technically that’s all you need to do, though in most cases you’ll want to set some additional options. The format for that is as follows:

Dropzone.options.WIDGET_ID = {
  //
};

To derive the widget ID for setting the options, take the ID you defined in your HTML and camel-case it. For example, upload-widget becomes uploadWidget:

Dropzone.options.uploadWidget = {
  //
};

You can also create an instance programmatically:

var uploader = new Dropzone(‘#upload-widget’, options);

Next up, we’ll look at some of the available configuration options.

Basic Configuration Options

The url option defines the target for the upload form, and is the only required parameter. That said, if you’re attaching it to a form element then it’ll simply use the form’s action attribute, in which case you don’t even need to specify that.

The method option sets the HTTP method and again, it will take this from the form element if you use that approach, or else it’ll simply default to POST, which should suit most scenarios.

The paramName option is used to set the name of the parameter for the uploaded file; were you using a file upload form element, it would match the name attribute. If you don’t include it then it defaults to file.

maxFiles sets the maximum number of files a user can upload, if it’s not set to null.

By default the widget will show a file dialog when it’s clicked, though you can use the clicked parameter to disable this by setting it to false, or alternatively you can provide an HTML element or CSS selector to customize the clickable element.

Those are the basic options, but let’s now look at some of the more advanced options.

Enforcing Maximum File Size

The maxFilesize property determines the maximum file size in megabytes. This defaults to a size of 1000 bytes, but using the filesizeBase property, you could set it to another value — for example, 1024 bytes. You may need to tweak this to ensure that your client and server code calculate any limits in precisely the same way.

Restricting to Certain File Types

The acceptFiles parameter can be used to restrict the type of file you want to accept. This should be in the form of a comma-separated list of MIME-types, although you can also use wildcards.

For example, to only accept images:

acceptedFiles: ‘image/*’,

Modifying the Size of the Thumbnail

By default, the thumbnail is generated at 120px by 120px; i.e., it’s square. There are a couple of ways you can modify this behavior.

The first is to use the thumbnailWidth and/or the thumbnailHeight configuration options.

If you set both thumbnailWidth and thumbnailHeight to null, the thumbnail won’t be resized at all.

If you want to completely customize the thumbnail generation behavior, you can even override the resize function.

One important point about modifying the size of the thumbnail; the dz-image class provided by the package sets the thumbnail size in the CSS, so you’ll need to modify that accordingly as well.

Continue reading %How to Build a File Upload Form with Express and Dropzone.js%


by Lukas White via SitePoint

How to Use the Android ListView Component

How to Test Your JavaScript with Selenium WebDriver and Mocha

This article was originally published on TestProject.

In case you are looking to write a functional test in JavaScript, the following tutorial provides UI automation engineers with the perfect structural reference material for JavaScript testing with Selenium WebDriver 3, Mocha and NodeJS.

These days, JavaScript is a ubiquitous web language which seems to overcome its ‘notorious’ past and has become a more solid platform not only for client-side, but for server domains too. Mocha.js, or simply Mocha, is a feature-rich JavaScript test framework running on Node.js, which provides the platform and the API for building standalone applications server-side using Google’s V8 JavaScript engine at its base.

*Note: to get started with this JavaScript tutorial, you’ll need to be familiar with the basics of NodeJS and the JavaScript programming language.

Tutorial Overview:

1. Mocha Test Construction

  • Introduction
  • Installation
  • Installing Chai Assertion Module
  • Test suite and Test Case Structure
  • Constructing Tests with Mocha
  • Running Mocha’s Test Suite and Test Cases
  • Managing Syncing of Async Testing Code

2. Using Javascript Selenium 3 API Integrated with MochaJS

  • Selenium Introduction
  • Selenium Installation
  • WebDriver Construction
  • Integrating MochaJS with Selenium WebDriver 3

Versions used:

  • Node version used: 6.10.1 (LTS)
  • Mocha: 2.5.3
  • WebDriverJS: 3.3.0

1. Constructing Tests with Mocha

Introduction to Mocha

As mentioned, Mocha is a JavaScript test framework that runs tests on Node. Mocha comes in the form of a Node package via npm, allowing you to use any library for assertions as a replacement to Node’s standard ‘assert’ function, such as ChaiJS. In addition, Mocha has several similar components to Jasmine, another popular test automation framework which we’ve mentioned in our research for Front End and Unit Test Automation Trends.

Mocha provides an API, which specifies a way to structure the testing code into test suites and test case modules for execution, and later on to produce a test report. Mocha provides two modes for running: either by command line (CLI) or programmatically (Mocha API).

Install Mocha

If Mocha is to be used in CLI, then it should be installed globally as Node.js.

npm install -g mocha

Install Chai Assertion Module

npm install --save chai

The –save option is used to install the module in the project’s scope and not globally.

Test Suite and Test Case Structure

In Mocha, a test suite is defined by the ‘describe’ keyword which accepts a callback function. A test suite can contain child / inner test suites, which can contain their own child test suites, etc. A test case is denoted by the ‘it’ function, which accepts a callback function and contains the testing code.

Mocha supports test suite setup and test case setup functions. A test suite setup is denoted by before while a test case setup applies beforeEach. beforeEach is actually a common setup for every case in the suite, and will be executed before each case.

As with the setup, Mocha supports test suite and test case teardown functions. A test suite teardown is denoted by after, while a test case teardown is implemented with afterEach, functions that are executed after a test suite and after each test case respectively.

Create a file that will ‘host’ the test suite, e.g. test_suite.js, and write the following to it;

describe("Inner Suite 1", function(){

    before(function(){

        // do something before test suite execution
        // no matter if there are failed cases

    });

    after(function(){

        // do something after test suite execution is finished
        // no matter if there are failed cases

    });

    beforeEach(function(){

        // do something before test case execution
        // no matter if there are failed cases

    });

    afterEach(function(){

        // do something after test case execution is finished
        // no matter if there are failed cases

    });

    it("Test-1", function(){

        // test Code
        // assertions

    });

    it("Test-2", function(){

        // test Code
        // assertions

    });

    it("Test-3", function(){

        // test Code
        // assertions

    });

});

Running Mocha Test Suite and Test Cases

Mocha supports execution of tests in three ways: Whole Test Suite file, tests filtered by “grep” patterns and tests grep filtering looking in a directory tree (recursive option)

Run whole Test Suite file:

mocha /path/to/test_suite.js

Run a specific suite or test from a specific suite file.

If a suite is selected then all the child suites and/or tests will be executed.

mocha -g “Test-2” /path/to/test_suite.js

Run a specific suite or test file by searching recursively in a directory tree.

mocha --recursive -g “Test-2” /directory/

For extensive CLI options:

mocha –-help

Managing Syncing of Async Testing Code

In case async functions are used with Mocha and not handled properly, you may find yourself struggling. If asyncing code (e.g. http requests, files, selenium, etc.) is to be used in a test case, follow these guidelines to overcome unexpected results:

Continue reading %How to Test Your JavaScript with Selenium WebDriver and Mocha%


by Dimos Koromilas via SitePoint

How to Test Your JavaScript with Selenium WebDriver and Mocha

This article was originally published on TestProject.

In case you are looking to write a functional test in JavaScript, the following tutorial provides UI automation engineers with the perfect structural reference material for JavaScript testing with Selenium WebDriver 3, Mocha and NodeJS.

These days, JavaScript is a ubiquitous web language which seems to overcome its ‘notorious’ past and has become a more solid platform not only for client-side, but for server domains too. Mocha.js, or simply Mocha, is a feature-rich JavaScript test framework running on Node.js, which provides the platform and the API for building standalone applications server-side using Google’s V8 JavaScript engine at its base.

*Note: to get started with this JavaScript tutorial, you’ll need to be familiar with the basics of NodeJS and the JavaScript programming language.

Tutorial Overview:

1. Mocha Test Construction

  • Introduction
  • Installation
  • Installing Chai Assertion Module
  • Test suite and Test Case Structure
  • Constructing Tests with Mocha
  • Running Mocha’s Test Suite and Test Cases
  • Managing Syncing of Async Testing Code

2. Using Javascript Selenium 3 API Integrated with MochaJS

  • Selenium Introduction
  • Selenium Installation
  • WebDriver Construction
  • Integrating MochaJS with Selenium WebDriver 3

Versions used:

  • Node version used: 6.10.1 (LTS)
  • Mocha: 2.5.3
  • WebDriverJS: 3.3.0

1. Constructing Tests with Mocha

Introduction to Mocha

As mentioned, Mocha is a JavaScript test framework that runs tests on Node. Mocha comes in the form of a Node package via npm, allowing you to use any library for assertions as a replacement to Node’s standard ‘assert’ function, such as ChaiJS. In addition, Mocha has several similar components to Jasmine, another popular test automation framework which we’ve mentioned in our research for Front End and Unit Test Automation Trends.

Mocha provides an API, which specifies a way to structure the testing code into test suites and test case modules for execution, and later on to produce a test report. Mocha provides two modes for running: either by command line (CLI) or programmatically (Mocha API).

Install Mocha

If Mocha is to be used in CLI, then it should be installed globally as Node.js.

npm install -g mocha

Install Chai Assertion Module

npm install --save chai

The –save option is used to install the module in the project’s scope and not globally.

Test Suite and Test Case Structure

In Mocha, a test suite is defined by the ‘describe’ keyword which accepts a callback function. A test suite can contain child / inner test suites, which can contain their own child test suites, etc. A test case is denoted by the ‘it’ function, which accepts a callback function and contains the testing code.

Mocha supports test suite setup and test case setup functions. A test suite setup is denoted by before while a test case setup applies beforeEach. beforeEach is actually a common setup for every case in the suite, and will be executed before each case.

As with the setup, Mocha supports test suite and test case teardown functions. A test suite teardown is denoted by after, while a test case teardown is implemented with afterEach, functions that are executed after a test suite and after each test case respectively.

Create a file that will ‘host’ the test suite, e.g. test_suite.js, and write the following to it;

describe("Inner Suite 1", function(){

    before(function(){

        // do something before test suite execution
        // no matter if there are failed cases

    });

    after(function(){

        // do something after test suite execution is finished
        // no matter if there are failed cases

    });

    beforeEach(function(){

        // do something before test case execution
        // no matter if there are failed cases

    });

    afterEach(function(){

        // do something after test case execution is finished
        // no matter if there are failed cases

    });

    it("Test-1", function(){

        // test Code
        // assertions

    });

    it("Test-2", function(){

        // test Code
        // assertions

    });

    it("Test-3", function(){

        // test Code
        // assertions

    });

});

Running Mocha Test Suite and Test Cases

Mocha supports execution of tests in three ways: Whole Test Suite file, tests filtered by “grep” patterns and tests grep filtering looking in a directory tree (recursive option)

Run whole Test Suite file:

mocha /path/to/test_suite.js

Run a specific suite or test from a specific suite file.

If a suite is selected then all the child suites and/or tests will be executed.

mocha -g “Test-2” /path/to/test_suite.js

Run a specific suite or test file by searching recursively in a directory tree.

mocha --recursive -g “Test-2” /directory/

For extensive CLI options:

mocha –-help

Managing Syncing of Async Testing Code

In case async functions are used with Mocha and not handled properly, you may find yourself struggling. If asyncing code (e.g. http requests, files, selenium, etc.) is to be used in a test case, follow these guidelines to overcome unexpected results:

Continue reading %How to Test Your JavaScript with Selenium WebDriver and Mocha%


by Dimos Koromilas via SitePoint

How to Test Your JavaScript with Selenium WebDriver and Mocha

This article was originally published on TestProject.

In case you are looking to write a functional test in JavaScript, the following tutorial provides UI automation engineers with the perfect structural reference material for JavaScript testing with Selenium WebDriver 3, Mocha and NodeJS.

These days, JavaScript is a ubiquitous web language which seems to overcome its ‘notorious’ past and has become a more solid platform not only for client-side, but for server domains too. Mocha.js, or simply Mocha, is a feature-rich JavaScript test framework running on Node.js, which provides the platform and the API for building standalone applications server-side using Google’s V8 JavaScript engine at its base.

*Note: to get started with this JavaScript tutorial, you’ll need to be familiar with the basics of NodeJS and the JavaScript programming language.

Tutorial Overview:

1. Mocha Test Construction

  • Introduction
  • Installation
  • Installing Chai Assertion Module
  • Test suite and Test Case Structure
  • Constructing Tests with Mocha
  • Running Mocha’s Test Suite and Test Cases
  • Managing Syncing of Async Testing Code

2. Using Javascript Selenium 3 API Integrated with MochaJS

  • Selenium Introduction
  • Selenium Installation
  • WebDriver Construction
  • Integrating MochaJS with Selenium WebDriver 3

Versions used:

  • Node version used: 6.10.1 (LTS)
  • Mocha: 2.5.3
  • WebDriverJS: 3.3.0

1. Constructing Tests with Mocha

Introduction to Mocha

As mentioned, Mocha is a JavaScript test framework that runs tests on Node. Mocha comes in the form of a Node package via npm, allowing you to use any library for assertions as a replacement to Node’s standard ‘assert’ function, such as ChaiJS. In addition, Mocha has several similar components to Jasmine, another popular test automation framework which we’ve mentioned in our research for Front End and Unit Test Automation Trends.

Mocha provides an API, which specifies a way to structure the testing code into test suites and test case modules for execution, and later on to produce a test report. Mocha provides two modes for running: either by command line (CLI) or programmatically (Mocha API).

Install Mocha

If Mocha is to be used in CLI, then it should be installed globally as Node.js.

npm install -g mocha

Install Chai Assertion Module

npm install --save chai

The –save option is used to install the module in the project’s scope and not globally.

Test Suite and Test Case Structure

In Mocha, a test suite is defined by the ‘describe’ keyword which accepts a callback function. A test suite can contain child / inner test suites, which can contain their own child test suites, etc. A test case is denoted by the ‘it’ function, which accepts a callback function and contains the testing code.

Mocha supports test suite setup and test case setup functions. A test suite setup is denoted by before while a test case setup applies beforeEach. beforeEach is actually a common setup for every case in the suite, and will be executed before each case.

As with the setup, Mocha supports test suite and test case teardown functions. A test suite teardown is denoted by after, while a test case teardown is implemented with afterEach, functions that are executed after a test suite and after each test case respectively.

Create a file that will ‘host’ the test suite, e.g. test_suite.js, and write the following to it;

describe("Inner Suite 1", function(){

    before(function(){

        // do something before test suite execution
        // no matter if there are failed cases

    });

    after(function(){

        // do something after test suite execution is finished
        // no matter if there are failed cases

    });

    beforeEach(function(){

        // do something before test case execution
        // no matter if there are failed cases

    });

    afterEach(function(){

        // do something after test case execution is finished
        // no matter if there are failed cases

    });

    it("Test-1", function(){

        // test Code
        // assertions

    });

    it("Test-2", function(){

        // test Code
        // assertions

    });

    it("Test-3", function(){

        // test Code
        // assertions

    });

});

Running Mocha Test Suite and Test Cases

Mocha supports execution of tests in three ways: Whole Test Suite file, tests filtered by “grep” patterns and tests grep filtering looking in a directory tree (recursive option)

Run whole Test Suite file:

mocha /path/to/test_suite.js

Run a specific suite or test from a specific suite file.

If a suite is selected then all the child suites and/or tests will be executed.

mocha -g “Test-2” /path/to/test_suite.js

Run a specific suite or test file by searching recursively in a directory tree.

mocha --recursive -g “Test-2” /directory/

For extensive CLI options:

mocha –-help

Managing Syncing of Async Testing Code

In case async functions are used with Mocha and not handled properly, you may find yourself struggling. If asyncing code (e.g. http requests, files, selenium, etc.) is to be used in a test case, follow these guidelines to overcome unexpected results:

Continue reading %How to Test Your JavaScript with Selenium WebDriver and Mocha%


by Dimos Koromilas via SitePoint

Build George Costanza’s Bathroom Finder using WRLD

This article was sponsored by WRLD 3D. Thank you for supporting the partners who make SitePoint possible.

“Anywhere in the city? Anywhere in the city: I’ll tell you the best public toilet.”

These are the words of George Costanza to Jerry Seinfeld in 1991. In that episode of Seinfeld; the visionary George invented an app before his time - the bathroom finder! If you’re a frequent traveller, a parent, or just someone who knows the importance of a clean and well-maintained space for some "serenity", you'll understand the utility of this idea.

George Costanza - magnificent facilities

So, this time in the second tutorial of our WRLD series we’re going to build a… let's call it a "facility finder app".

It’s not the first time someone has tried this mind you. In 2010, bathroomreview.ca did just that (as described in Forbes). But the site is no longer operational.

We covered quite a bit of ground in the last tutorial, this time round, we’re going to reuse some of that learning. For instance, we’ll use ParcelJS to build our static files, but we won’t go into too much detail about how to set it up again. We’ll also highlight buildings and set the appropriate weather conditions and time of day, depending on what they are for the user. If you’re unsure about how these work, refer back to the previous tutorial.

In this tutorial, we’re going to cover these topics:

  • Creating a simple AdonisJS server-side API (to cache location data and handle CORS requests).
  • Requesting public facilities data, from refugerestrooms.org, if there are no cached locations within 10 meters of the user. We’ll use the Google Distance Matrix API to calculate the distance between points of interest.
  • Highlighting buildings with public facilities, colored to match their rating. Green for good, red for bad. Each building will have an info card for extra info (like how to reach the bathroom).

At the end, we’ll talk a bit about how to turn this kind of app into a viable business. That’s really the point of this isn't it? The WRLD APIs provide tools to visualise real-world data in a map of the real world. Our job is to work out how to use this technology for commercial applications!

The code for this tutorial can be found on Github. It has been tested with a modern versions or Firefox, Node, and macOS.

Getting Facility Data

Let’s begin by learning how to get the facility data, and the form we get it in. We’re going to use refugerestrooms.org as a source of data. We learn that we can search by latitude and longitude, by looking at the documentation. In fact, we can make the following request, and see a set of facilities close to my location:

curl http://ift.tt/2B67V5u? ↵
    lat=-33.872571799999996&lng=18.6339362

There are a few other parameters we could be specifying (like whether to filter by accessible and/or unisex facilities), but the main thing this gives us is a way to plug coordinates into a search and get close-by locations.

We can’t just call this from the browser, though. There are all sorts of security reasons why this is disallowed. There are also performance reasons. What if 10 people made the same request, standing 10 meters apart from each other? It would be a waste to fire off 10 requests to the same remote server, when we could serve it faster from a caching proxy.

Instead, we’re going to set up a simple AdonisJS caching API. Our browser app will send requests to the AdonisJS API, and if there’s no “nearby” data; it will send a request to the Refuge API. We can’t spend too much time on the details of AdonisJS, so you’ll have to check out the documentation for details.

I’m also just about done writing a book about it, so that’s the best place to learn how it works!

The easiest way, to create a new AdonisJS app, is to install the command-line tool:

npm install --global @adonisjs/cli

This enables the adonis command-line globally. We can use it to create a new application skeleton:

adonis new proxy

This takes a little while, since it’s installed a few things. When it finishes, you should see a message to run the development server. This can be done with:

adonis serve --dev

Open up http://127.0.0.1:3333 in your browser, and you should be greeted by this beauty:

Adonis welcome screen

Creating Migrations and Models

Let’s story the search data in a database. AdonisJS supports a few different engines, but we’ll use SQLite for the sake of simplicity. We can install the appropriate driver, using:

npm install --save sqlite3

Next, let’s make a migration and a model. We’re only interested in the coordinates used to search, and the returned JSON. If the coordinates are close enough to where a user is searching for, we’ll reuse the existing search response instead of re-requesting the search data.

We can use the adonis command-line utility to create migrations and models:

adonis make:migration search
adonis make:model search

That creates a couple files. The first is a migration, to which we can add three fields:

"use strict"

const Schema = use("Schema")

class SearchSchema extends Schema {
    up() {
        this.create("searches", table => {
            table.increments()
            table.string("latitude")
            table.string("longitude")
            table.text("response")
            table.timestamps()
        })
    }

    down() {
        this.drop("searches")
    }
}

module.exports = SearchSchema

This is from proxy/database/migrations/x_search_schema.js

We’ve added the latitude, longitude, and response fields. The first two make sense as string even though they contain float data, because we want to do sub-string searches with them.

Next, let’s create a single API endpoint:

"use strict"

const Route = use("Route")

// we don't need this anymore...
// Route.on("/").render("welcome")

Route.get("search", ({ request, response }) => {
    const { latitude, longitude } = request.all()

    // ...do something with latitude and longitude
})

This is from proxy/start/routes.js

Each AdonisJS route is defined in the routes.js file. Here, we’ve commented out the initial “welcome” route, and added a new “search” route. The closure is called with a context object; which has access to the request and request objects.

We can expect search requests to provide latitude and longitude query string parameters; and we can get these with request.all. We should check to see if we have any vaguely related coordinates. We can do this by using the Search model:

const Search = use("App/Models/Search")

const searchablePoint = (raw, characters = 8) => {
    const abs = Math.abs(parseFloat(raw))
    return parseFloat(abs.toString().substr(0, characters))
}

Route.get("search", async ({ request, response }) => {
    const { latitude, longitude } = request.all()

    const searchableLatitude = searchablePoint(latitude)
    const searchableLongitude = searchablePoint(longitude)

    // console.log(searchableLatitude, searchableLongitude)

    const searches = await Search.query()
        .where("latitude", "like", `%${searchableLatitude}%`)
        .where("longitude", "like", `%${searchableLongitude}%`)
        .fetch()

    // console.log(searches.toJSON())

    response.send("done")

    // ...do something with latitude and longitude
})

This is from proxy/start/routes.js

We begin by importing the Search model. This is a code representation of the database table we created (using the migration). We’ll use this to query the database for “nearby” searches.

Before we can do that, we need a way to search for nearly coordinates. The searchablePoint function takes a raw coordinate string and creates an absolute float value, removing the optional - from the front of the string. Then, it returns the first 8 characters of the coordinate string. This will shorten -33.872527399999996 to 33.872527. We can then use these 8 characters in a SQL “where like” clause, to return all searches with similar coordinate strings.

AdonisJS uses the async and await keywords to great effect. Methods like Search.query return promises, so we can await their results while still writing 100% asynchronous code.

I’m skipping a lot of AdonisJS details, which I really don’t like doing. If you’re struggling with this part; speak to me on Twitter, and I’ll point you in the right direction.

Matching Nearby Locations

Now that we’ve got the “nearby” locations, we can compare their relative distances to where the user is standing. If you don’t yet have a Google API key, refer back to the previous tutorial for how to get one. We’re about to be the Google Distance Matrix service:

http://ift.tt/1zFyAP1? ↵
    mode=walking& ↵
    units=metric& ↵
    origins=-33.872527399999996,18.6339164& ↵
    destinations=-33.872527399999997,18.6339165& ↵
    key=YOUR_API_KEY

The Distance Matrix service actually allows multiple origins, so we can combine all of your previous searches into a longish origin string:

const reduceSearches = (acc, search) => {
    const { latitude, longitude } = search
    return `${acc}|${latitude},${longitude}`
}

Route.get("search", async ({ request, response }) => {
    const { latitude, longitude } = request.all()

    // ...get searches

    const origins = searches
        .toJSON()
        .reduce(reduceSearches, "")
        .substr(1)

    // console.log(origins)

    response.send("done")

    // ...do something with latitude and longitude
})

This is from proxy/start/routes.js

We can convert the search results into an array of objects. This is useful because we can reduce the array, combining each search’s latitude and longitude into a string. That string will begin with a |, so we need to get the string starting at index 1.

Continue reading %Build George Costanza’s Bathroom Finder using WRLD%


by Christopher Pitt via SitePoint

Kalium Restaurant

‘Kalium’ is a multi-use WordPress theme with a lovely Restaurant layout option. Features include a beautiful intro load transition against a full screen background video, a sticky header navigation (that smooth scrolls to the relevant sections), a dedicated head chef section, food menu with category filter, a image gallery of food with bigger image pop up view, guestbook, blog feed, Google Maps, a reservation form and a great looking footer with contact info. Awesome to know the WordPress theme comes with WPBakery Page Builder (formally called Visual Composer, valued at $45) and Slider Revolution (valued at $25) plugins bundled in.

Full Review | Direct Link


by Rob Hope @robhope via One Page Love