AngularJS: How To Call A Controller From Another Controller

In AngularJS when it comes to communicating between controllers, one would naturally assume to reference another controller you can simply inject it into another controller and call its methods: however, you cannot do that.

Method 1: Shared service

One such method of communicating and sharing methods betweens multiple controllers is a shared service. Here you might put in a method for closing a overlay or redirecting the browser somewhere or checking the state and value of a variable.

The following example assumes you have created a service called “myService” and you have a method called updateVal and getVal for getting and setting values.

var myModule = angular.module('myapp', []);

myModule.controller('myController', ['$scope', 'myService', function ($scope, myService) {
    myService.updateVal('name', 'Dwayne');
}]);

myModule.controller('otherController', ['$scope', 'myService', function ($scope, myService) {
    if (myService.getVal('name') === 'Dwayne') {
        alert('The name is ' + myService.getVal('name'));
     } else {
         alert('There is no Dwayne');
     }
}]);

This is my preferred approach for sharing data and methods between controllers for a number of reasons; it makes things cleaner, it keeps logic separate from your controllers and above all: it makes things easier to test.

Method 2: Events

In some cases, events can be a lot cleaner than using a separate service. Triggering an event say for example when you open up an overlay, close it or perform some action you want to inform other controllers about can be done emitting an event on $scope.

var myModule = angular.module('myapp', []);

myModule.controller('myController', ['$scope', function ($scope) {
    $scope.$on('profile-updated', function(event, profileObj) {
        // profileObj contains; name, country and email from emitted event
    });
}]);

myModule.controller('otherController', ['$scope', function ($scope) {
    $scope.$emit('profile-updated', {
        name: 'Dwayne',
        country: 'Australia',
        email: 'somedude@example.com'
    });
}]);

Conclusion

Pick whichever feels right. I personally prefer method 1 because as I mentioned, it is testable, it is cleaner and keeps things separate. But using events also have their advantages as well.

 

I Heart Object.observe()

If you have used AngularJS, or EmberJS and any other front-end Javascript based framework, then you would be familiar with the concept of data binding. Essentially being able to watch a Javascript object for changes and then call a function when this takes place.

Currently without using a third party library which implements a non-native method for observing changes in a object like Angular or a polyfill, there is no cross-browser method for observing objects for changes which doesn’t involve some kind of hack at the expense of performance.

While Object.observe() is really only currently supported in Chrome, it is without-a-doubt the future of Javascript. It means that the need for a front-end framework is lessened, not for now, but eventually, it will. Sadly, Object.observe() is not scheduled to land until ES7.

A basic example:

var someObj = {};

Object.observe(someObj, function(changes) {
    changes.forEach(function(change) {
        console.log({
            propertyNameAffected: change.name,
            oldValue: change.oldValue,
            changeType: change.type,
            affectedObject: change.object
        });
    });
});

// This will trigger an event and output the following in the console
// {propertyNameAffected: "myVal", oldValue: undefined, changeType: "add", affectedObject: Object}
someObj.myval = 'Dwayne';

// Changing the value of a pre-existing property will output the following in the console
// {propertyNameAffected: "myVal", oldValue: "Dwayne", changeType: "update", affectedObject: Object}
someObj.myval = 'Dwayne Again';

// Deleting the property from the object will output the following in the console
// {propertyNameAffected: "myVal", oldValue: "Dwayne Again", changeType: "delete", affectedObject: Object}
delete someObj.myval;

One of the best polyfills out there for Object.observe() support in all browsers, through the use of either the native method or dirty-checking is Observe-js.

As you can see one of the most touted benefits of front-end frameworks is data-binding and eventually people will favour native Javascript over frameworks as tasks that once required polyfills/frameworks/libraries to do can be done in a few lines of native JS.

The future is bright, man.

 

All About The HTML5 FileReader API

Since the recent announcement of HTML5 being finalised, we can finally talk about all of the awesome additions to HTML5 without fear of them changing. Once such addition to HTML5 is the FileReader API which allows you to work with files locally on a hard drive.

The FileReader API is seriously undervalued and surprisingly a few developers I have spoken with who know about it, have not used it or assumed that it was not really supported and thus, ignored it. And some others have not heard about it at all.

Some use cases for the FileReader API include:

  • Allowing the user to upload a gallery of images within your web application and being able to show them an instant thumbnail preview before the files are uploaded to the server
  • Avatar image upload and cropping functionality all on the client-side. A user can upload an avatar image, see the image they uploaded and then crop it before the cropped version is sent off to the server
  • Profile image upload functionality

Support is surprisingly decent. It works in all modern browsers and also in IE10 and up. There is however a polyfill for < IE10 which uses Flash, but still allows you to use FileReader (albeit not as intended).

The FileReader API also supports a whole bunch of events for errors, progress, changes and more. Methods for cancelling file uploads, getting the contents of an uploaded file (image or text file contents) and the usual methods/events you would expect from a fully featured FileReader API.

Traditionally you would handle a lot of these tasks using something like Flash and server side processing. Now that the FileReader API is more widely supported, we can phase out solutions that rely on Flash and heavy server-side processing (as you know processing files server-side can be costly).

You can read up on the FileReader API here on Mozilla Docs. You can also see a whole bunch of examples here on Mozilla Docs as well which show it working with drag and drop functionality as well.

 

DOMDocumentFragment vs innerHTML

When it comes to Javascript, there are many ways you can skin a cat as they say. When it comes to inserting HTML into a page, unless you are using a Javascript library like jQuery or something like React.js or AngularJS, you most likely are using innerHTML.

Even the html() method in jQuery internally uses the innerHTML property to insert HTML into your element(s), as do many other libraries and frameworks.

When it comes to performance sadly, innerHTML proves just how shitty it actually is when you need to bulk insert some HTML into your page. While the need to insert hundreds or thousands of elements into a page might be pretty niche, it is good to know when limits are being reached.

Enter DOMDocumentFragment. You would be surprised how many developers I meet who do not even know DOMDocumentFragment exists, what it does or when to use it.

The fantastic Mozilla web docs [here](The DocumentFragment interface represents a minimal document object that has no parent. It is used as a light-weight version of Document to store well-formed or potentially non-well-formed fragments of XML.) describe DOMDocumentFragment:

The DocumentFragment interface represents a minimal document object that has no parent. It is used as a light-weight version of Document to store well-formed or potentially non-well-formed fragments of XML.

While the benefits of using DOMDocumentFragment for inserting a few elements might be negligible, you get the benefit or reducing reflows and repaints, keeping performance in your web application high and giving yourself some room to grow.

This old JSPerf test is an oldie but a goodie and clearly shows the MASSIVE performance gains you get using DOMDocumentFragment over a traditional innerHTML call.

However, things tend to get more complicated when it comes to mobile performance. Rather than reiterate things that have been said before, I implore you to read this article and decide if the weird caveats of mobile phone browsers favouring innerHTML over DOMDocumentFragment in a few cases is an issue for you.

 

AngularJS: What’s The Deal With $scope.$apply, Yo?

Chances are if you have been using AngularJS for a little while that you have come across $scope.$apply() at some point, whether it be your own code or someone else’s. What the heck is $scope.$apply() and why should you care?

To understand why we have $scope.$apply we have to understand that Javascript is turned based. When you write your Javascript code, it does not run all at once, code is run in blocks. So it is possible when you change a value within Angular and a $digest cycle has already been run, your changes will not be seen.

When you make a change outside of a non-Angular method, so a native DOM event or method in a third party library like jQuery, Angular does not know anything changed and as such, will not acknowledge anything has changed. All $scope.$apply does is basically says: “Hey Angular, a value changed bro, thought you should know, so you can tell your listener homies about it

When you use $scope.$apply it will trigger a $digest cycle which ties into two-way binding which AngularJS uses quite heavily. Effectively $scope.$apply is a wrapper around $digest. Incorrect use of $apply can result in a “digest already in progress” error which means you tried using $apply when a $digest is already running.

Actions in AngularJS that trigger a $digest can include; in-built Angular directives like ng-repeat, ng-hide, ng-show, ng-click and even $http calls. If you try using $scope.$apply within one of these calls or even within a $timeout, you will get issues.

You should ideally only ever use $digest or $apply inside of an asynchronous call to let Angular know when you have made some changes as the official wiki details. And you should never use $apply or $digest within a controller, only within directives and services.

A classic example that does the runs is using a setTimeout (you would ideally use a $timeout but for example sakes):

setTimeout(function () {
    $scope.$apply(function () {
        $scope.message = "Timeout called!";
    });
}, 3000);

In the above example, after 3 seconds, the timeout function will resolve itself and set the $scope variable “message” to ‘Timeout called!’ because we are updating code from a non-Angular method, we need to call $apply to tell Angular about the changes.

In a nutshell $scope.$apply tells Angular and any watchers that values have been changed and to go back and check if there are any new values. This keeps things within the Angular context regardless of how you made a change, like in a DOM event, jQuery method, etc.

 

Bulk Linux Chmod Commands For Files & Directories

Recently in Ubuntu which I use for my hosting operating system of choice I needed to bulk change permissions on a bunch of folders and files. I needed to set permissions on folders within a WordPress installation to 755 and all files in theme, plugin and asset directories to 644.

While my command line-fu is not very strong, I was able to work it out and I thought I would share my findings here for others.

To bulk change permissions on folders:

find /yourlocationwithfolders -type d -exec chmod 755 {} \;

To bulk change permissions on files:

find /yourlocationwithfolders -type f -exec chmod 644 {} \;

You can use the -R recursive flag with chmod, but it will not allow you to set permissions on all folders and files, but rather on everything (which is rare you would want to set permissions on everything to be the same).

 

My Experience Buying A Playstation 4 In The US & Shipping To Australia

It is no secret that buying games, software, online services and electrical goods overseas in the US can cost considerably less than it does if you purchase in Australia. However there are some misconceptions about doing so.

Is the Playstation 4 region locked?

First things first, the Playstation 4 console is NOT region locked. This means games from anywhere in the world will work on the Playstation 4 regardless of where you bought your console or games. This is however not the case for movies which are sometimes region locked, but who seriously buys physical forms of movies anyway?

Can I plug a US bought Playstation 4 into an Australian wall socked?

Yes. Most electronic devices these days have multi-voltage power supplies, the Playstation 4 is no exception. The only difference between worldwide Playstation 4 consoles is the cord. It would not make economical sense for a company to have multiple variants of one power supply.

The first thing you will want to do is replace the power cord with that of an Australian adaptor figure–8 or shotgun connector cable. This is the kind of cable that you probably already have lying about for a set-top box, camera charger or a million other devices. In-fact if you own a Slim/Super Slim PS3 or PS Vita, the cord will work on your Playstation 4.

Can I play Australian bought games on a US bought Playstation 4?

Yes. Always check the disc box to ensure the game is not region locked (most games are not, but I have heard cases where a developer has locked the region). There is however a DLC catch which is explained next…

How does DLC work for purchased games?

There is a slight caveat with purchasing DLC for your games. The DLC purchased for the game must be done so through the store for the country you bought the game in. This is because DLC is mostly always region locked. Confused?

If you bought Battlefield 4 from the USA for your console for example, when EA releases DLC for Battlefield 4, you need to have a US Playstation Network account to buy the DLC for the game. An Australian PSN account will NOT allow you to buy DLC for a US bought game (or so in my experience).

Playstation Network accounts

If you choose to setup a US PSN account, there is another caveat. Most Australian credit cards will NOT work on a US PSN account. You have to weigh up if cheaper games and earlier DLC appeal to you. That said, there is no disadvantage of having a US PSN account in Australia.

To top up you can purchase codes off of Amazon to circumvent the geolocking issue of needing a US issued credit card and address to match which is what most people do.

Warranty

You have to weigh up if forgoing any kind of warranty is a problem for you. For me, I figured a year after the PS4 was released, my chances are quite low of actually running into issues and on the rare occasion something happens, I will have to pay to ship it back.

The benefit of buying in Australia and paying $100 more (after conversion at current rates it is most likely a saving of around $60) is that we have some of the best consumer rights laws in the world. If it breaks, you are entitled to a replacement or refund within the first two years. Some would argue the warranty is worth the extra $60 or so.

Conclusion

Overall there is not much else to say about the experience. The Playstation 4 being region free means you can buy one from anywhere, the PSN account issue can be annoying, but it is hardly a deal breaker.

 

Chrome For Mac OS X In 64bit Glory

Mac users who use Google Chrome today will receive a special treat. Chrome for Mac OS is now 64bit in the version 39 update which was pushed to the stable channel today.

Along with a whole bunch of security fixes and performance improvements, the new 64bit only version will allow for greater stability, performance and above all better security going forward.

Those who have been using the beta/alpha versions of Chrome have had 64bit support for sometime now and during testing it was reported most people saw noticeable improvements (especially when it came to video performance).

 

Google Announces “Mobile Friendly” Testing Tool/Result Tweaks

In a move signalling that Google is well and truly dedicated to improving the user experience of the web, they have announced a new tool that checks if your site is mobile friendly, as well as changes to their search results.

The tool can be found here. Fortunately all of my sites I tested were mobile friendly (including this blog).

Not only that, but Google will also be showing alongside the search results of a page whether or not it is mobile friendly as well. While it is too early to say so, whether this has an effect on the search engine rankings of websites who are and are not mobile friendly remains to be seen.

Now might be a good time to test your own sites and if they are not mobile friendly, fix them up before it starts to mean something and affects your search engine rankings with Google.

Either way, this is a welcome change. If search rankings are affected by lack of mobile friendly site, is that such a bad thing? Traffic on handheld and mobile devices is easily 2:1 that of desktop Internet traffic (expected to double again by 2020).

 

I Refuse To Fund Misogyny: Goodbye Uber

I am a longtime Uber lover and user. Without fail any trip I have taken to the United States has involved the use of Uber for getting around over hiring a car or catching a taxi.

I am currently in the US on a three month trip and for the last two months I have been using Uber almost on a daily basis. In-fact, I have racked up more Uber rides the last two months than I have in the last two years combined (which is a lot).

But after the recent remarks from SVP (senior vice president) of Business for Uber, Emil Michael making threatening comments about journalist Sarah Lacy of Pando Daily because he felt like Uber was being targeted, it is at that point I realised I have been too tolerant of Uber and its questionable business ethics and attitudes towards women and its customers. We all have.

This sadly is not Uber’s first controversial time in the spotlight. The company has had more scandals and controversies than a lead actor in a soap opera in the last two years. Remember the time that it was revealed Uber had a playbook of sorts for sabotaging their competitor Lyft?

I believe the service is great and while I have not had any overly bad experience using the service itself, I refuse to fund a company so morally bankrupt and misogynistically driven. It seems Uber has a problem that extends right down to its roots: the executives tasked with steering the ship that is Uber.

Things need to change. It is obvious there is undoubtedly a culture of misogyny and outdated attitude towards women in Silicon Valley. The Uber board and its investors need to take a stand, Emil Michael needs to be held accountable for his statements, whether they were on or off the record.

Uber have just lost themselves a customer and from now on I will be using their competitors offerings instead. I tried out Lyft for the first time the other day and I must say, I was impressed with their application, service and ability to tip drivers (handy when you want to tip for a driver helping with your luggage and have no cash on you).

 
Real Time Analytics