Angular 2 Routing is bit complicated when compared to routing in Angular 1.x but it is very powerful. We hope to clear up some of the common confusion when setting up routing and provide some practical examples as references.
Understanding routing in you application is the key to creating a single page application. Routing is what allows view navigation in your application like ‘detail views’, end user bookmarking and even allows you to set up a ‘logged in’ version of your applications views.
Routing isn’t included by default in Angular 2, in fact you have to explicitly include it as a library. I also will say, it’s not incredibly intuitive to configure. We’ll take some time to explain the history of the router and dive into some of the basic concepts.
Basic Concepts of Routing in Angular 2
The router itself is implemented in the optional Router Module, which is kept separate to keep the base library size low. Include it in your main module like this:
The base HREF is the starting point for your application and is used to create your home route. It’s this starting point that your browser will also use to create a history to prevent ‘breaking the back button’ which is always a sticking point in SPAs.
Here’s the syntax you need to add to you html:
Configuration & Routes
const routes = [
// Default, or home, path. This matches your Base HREF
// Wildcard, or the 'catch-all' route pattern. If the requested
// route does not match anything above, this route is displayed.
Resolves & Guards
Resolves are services that must be completed before allowing the route to be accessed and loaded. This is how we can ensure that the data is available for the route prior to allowing the user to access the route.
A quick example of this would be a UserResolve class that retrieves a list of users before displaying the route.
Guards are a method to prevent a route from being accessed unless a certain state is met.
A quick example of this would be a LoggedInGuard class that prevents a user from accessing a route unless they are logged in.
Child routes are a way to add specific routes to a feature.
Example 1: A One Route Application
Below is an example of an application with a single route. This illustrates including the router module, a base href and a very basic route configuration.
Example 2: A One Route Application with a Resolve
Below is an example of an application with a single route that requires a service to resolve a data retrieval before rendering.
Example 3: A multiple route application with a child route
Below is an example of an application with two routes and a child route.
While it may take some time to completely wrap your mind around routing in angular it’s clearly an important part of creating a real SPA. Don’t be afraid to take and reference your own notes!
Interaction with data in Angular 2, internally and from external sources, is based around the concept of services. Learning more about services is integral to learning how to create an Angular 2 component or application.
Angular 2’s biggest strength is the reliability of encapsulation and re-use, which means passing data to and between components can be a pain at first. You are highly discouraged from getting data from the DOM, making AJAX calls in your components is a no-no. How are you supposed to get data to your things?
This is where you start to use Angular Services. Services are an injectable class that allows you to keep all your functionality in one place. Here’s the official definition of a service in Angular 2 from the docs:
A service is a class with a focused purpose. We often create a service to implement features that are independent from any specific view, provide shared data or logic across components, or encapsulate external interactions.
You have data you need from an AJAX endpoint? Create a service.
You want to maintain state for an object that multiple components? Create a service.
Want to do anything cool with some data across your application? Create a service.
For those of you familiar with the pattern, Services in Angular 2 are really Singleton Service models. Its a single instance you pass around. It has a state, it has some methods. Its easily mocked and you know where the ‘meat’ of your application is at all times. It allows you to move the data manipulation out of the display code entirely.
Coming from a Vanilla JS background all of this may seem a little over complicated. While simplicity is something to strive for, there are good reasons for this level of abstraction:
Encapsulating the functionality of your services is a good practice
You can focus on functionality in your components with a well defined service
Mocking a service is easier than mocking an environment
Here’s some examples of services in action:
Example 1: A Simple String Returning Service
This is an example of a simple data service providing some data to a component. While extremely simple, it shows how to get data ‘into’ a component from an outside source:
The component itself relies on the service to provide the data to the front end. The value of ‘bar’, displayed in the component’s template actually comes from the service itself. When the component loads, it calls the “getBar” method of the service which returns a simple string.
While this example might seem very trivial, it lays some groundwork for the other examples. A service provides data external from the component in an ‘agreed’ upon way. This contract allows us to take some control of how we get the data away from the component, which should really just focus on how the data should be displayed.
Example 2: A service that allows us to share data between more than one component
This is an example of a service that allows a total of three components to interact together.
If you look at the code in the example, this small ‘app’ has three components that each include the CounterService. This extremely simple service allows us to interact with a single integer variable that can be incremented and decremented via two completely separate component’s buttons.
Again, while maintaining a ‘contract’ we can allow each one of these components to focus on the display and events rather than the actual manipulation of the data.
Example 3: A service that provides data from an AJAX (external) source
This is an example of an AJAX service providing data to a component. A ‘locally’ hosted JSON file is retrieved via AJAX in the service itself and then sent to the component. This component is able to interact with the data entirely through the service itself. This level of abstraction allows the component to strictly focus on the display and styling of the data provided by the service.
Promises vs Observables in your AJAX services
Promises are great and a well trod subject, I’ll leave it up to you to read more about their benefits (or you can revisit my previous blog post: http://blog.arroyolabs.com/2016/04/angularjs-2-ajax/). Observables, when compared to promises, allow you to specify not only when something is ‘done’ but when something has changed.
This most definitely comes in handy when you create a service like the example above that allows you to detect when any changes occur from your service.
A Final Note
While the final architecture of your application or bundled component is really a choice you need to make, I hope we were able to clear up some of the basics of using services in Angular 2.
ProtractorJS is a robust and easy to use e2e test framework specifically designed for testing AngularJS applications. With some simple edits and a slight change in thinking, you can also use it to test your non-angular web apps and provide some sanity to your testing strategy across projects.
ProtactorJS is an end to end test framework from Google used to test AngularJS Apps. While similar to existing tools like CasperJS, ProtractorJS is specifically designed for use with AngularJS.
With minimal effort you can use Protractor with your Vanilla JS web app as well. Why would you do this?
For one, using the same test framework for all you apps provides some sanity to writing tests for all of your projects. And you can’t honestly tell me you have all your apps converted to AngularJS already.
Second, it’s gaining popularity and for good reason. It’s a solid testing framework and is relatively easy to set up. Also, it has the backing of a very well known company (cough cough, Google) so it will be around for a long time.
Finally, it’s use of Jasmine and suite structures allow you to write some flexible tests. Encapsulate your logic, group stuff in ways that make sense. No more fragile tests!
Enough stumping, let’s get to the parts you actually care about.
You can use other frameworks, but my preference is Jasmine.
Selenium Server & Webdriver
Protractor interacts with your tests using Seleniums Server and Webdriver. You can run Selenium locally or use a hosted service like Sauce Labs.
Local installation and setup is turn key simple using NPM.
A Web server
Since your tests use a real browser to execute, you need a host of some kind.
It’s entirely possible to run your tests against an external server (like your staging server), but in practice I like to serve locally. In our example I used the local-web-server NPM package.
Protractor Test Concepts
Again, I’ll point you to the main documentation for longer descriptions of the concepts, I wanted to point out some that need to be discussed when prepping your protractor tests for execution on your VanillaJS app.
A config file sets up some required variables and tells Protractor how to run its tests. This includes a directory where your tests are held, the testing framework you use to write your tests and the address to the selenium server instance you use to run Karma.
Spec File (Test Suite) – “Describe”
Test suites are groups of testing conditions that focus on a particular section or part of your application. Using Jasmine, these are structure with the “describe” function and a brief string indicating the portion of the application under test.
Hooks are small functions that are called during test executions. An example is the beforeEach hook we use to set up our tests for use with non-angular code. See the note below on exactly what goes in this hook.
Test Blocks – “It”
Test blocks are identified by an “it” phrase that describes in simple terms what you expect to happen. This is useful for turning user stories into tests like “User Registration Form should validate user input”.
These test blocks do have some minimal setup but are mostly for performing actions and asserting values. Check out our example code to see some of this in action.
Page Objects are similar to test fixtures in other testing frameworks, but thats underselling the usefulness of this concept. Page Objects are small JS objects where you can encapsulate and abstract out common page elements and share between your tests.
Use these to abstract out some commonly tested things, like getting the text or value from a page element. If you use your page object in all your tests, you only have one place to update when a change is made (instead of having to update ALL your test suites).
Running Protractor on your Vanilla JS App
Like we noted above, Protractor was designed for testing AngularJS apps by default. A large difficulty in e2e web app testing is knowing when something has rendered on the page and is ready to have some interaction. AngularJS abstracts how you work with the DOM in JS as well as having some control over how something is determined to be “ready” using Zones.js.
Three major things need to be done to make sure your Protractor test will actually work with out Angular:
Expose the web driver in a way you can access the DOM for interaction.
Due to the nature of how Angular abstracts the DOM and how it takes over all the app’s event cycles. We need to expose the Selenium Web Driver in a way you won’t hate.
Add this line to your onPrepare hook in the config file to assign the web driver to an global variable called “dv”
global.dv = browser.driver;
Tell the test not to wait for Angular to give the “go ahead, I’m ready” signal.
Protractor uses Angular to tell it when the page under test is ready to be tested. We need to skip this in order to test our non-angular app.
Add this to each test suite’s beforeEach hook to make sure the test knows to run as we expect
dv.ignoreSynchronization = true;
Start thinking about your tests with Promises
While I’m sure most of us at this point have seen and used Promise style functions. When testing an Angular app, using the default locators is easy. Since we are testing our app using the native web driver, we need to use a promise to allow Selenium to return the DOM element itself. Really though, it’s not that tough.
Here is an example where we want to assert the value of an element with the css ID of “foo” using a series of chained promises.
Protractor does indeed have a very basic plugin system that gives end users some ways to extend base functionality. I’m still trying to understand this system myself (I haven’t figured out how to use a plugin that isn’t globally installed) I have found one that is very useful called jasmine2-protractor-utils.
I’ll leave some of the longer explanation of this plugin to the author, but my favorite feature is the ability to take a screenshot of the browser in the test on suite or block failure. Once you get things up and running so your tests are running automatically, having some visual artifacts of a failed test will help you replicate and diagnose what and how things went wrong.
Example – Movie Vote
Here is an example (very small) Web App demonstrating a very basic suite of Protractor tests. You can simply clone this repo, install the required packages using the package.json file and run these tests. Simply follow the instructions in the README.md file.
With any luck you have moved beyond the anti-patterns of yore and you have abstracted your JS functionality into some coherent objects to maintain your sanity. Now it’s time to start testing these pieces of code.
I should note, unlike many other xUnit frameworks, Jasmine is BDD or a Behavior Driven Development framework. This is a fancy way of saying you structure your test suites in a way where you test ‘behavior’ scenarios rather than simple methods and functions.
Karma is a test runner that executes your unit tests in a ‘real browser’. In short, it runs your Jasmine tests in a real browser via websockets.
This means you can test using a headless browser like PhantomJS or a real browser like Chrome. This really becomes useful when you need to test in multiple browsers, but especially useful when you need to run your tests locally (via Chrome) or remotely on a CI (in our examples below we run the unit tests using Chromium. More on that later).
There’s a little setup involved with Karma, but not too much. Honestly, it took less time to get my Karma config created than it did to write my example unit tests.
Travis CI is a hosted continuous integration tool that will watch your repo and execute your tests on certain conditions like a push or a pull request. It is also is free for your open source, or at least your public, Git Hub repos. Best of all, you can also show a super cool ‘build status’ badges in your github readme page.
Travis CI: Using Chromium
Please note that if you run your KarmaJS tests locally using Chrome, you will need to make sure Travis CI knows to use the open source equivalent Chromium as it fit’s into its ‘free tier’ licensing scheme.
Below are the key things you need to set this up, all of this code can be found in our examples below:
We need to tell Travis to install the Chromium browser package when it creates the container. Add the noted entry (‘export CHROME_BIN=chromium-browser’) into the “before_install” section of your travis config.
Next we need to determine if our tests are executed by Travis, and if so, tell Travis to use Chromium (which is aliased to CHROME_BIN from our config above) when exec’ing our tests:
// Config values to allow TravisCI to run chrome in it's container
browsers: ['Chrome', 'ChromeCanary'],
// tell TravisCI to use chromium when testing
// Detect if this is TravisCI running the tests and tell it to use chromium
config.browsers = ['Chrome_travis_ci'];
I think its easiest to look at config from our example code to see exactly where this is placed in your config: https://github.com/arroyolabs-blog/movie-vote/blob/master/karma.conf.js
Testing is a very important part of software development and can be fun and easy once you get things set up to run automatically. Hopefully after reading this post you will have a good idea of how to integrate unit testing into your JS projects.
The Shadow DOM is a way to create elements that are not affected by the same attributes and properties as those in the Light DOM. The Shadow DOM provides true scope encapsulation; your element’s CSS and JS are scoped to it alone! Think of the Shadow DOM as a lightweight version of an iframe.
When you think about creating a web page, we typically think about the HTML elements we structure and style and interactive with using CSS and JS. For the sake of simplicity, we will call the elements you see rendered as the Light DOM.
The Shadow DOM by contrast is a way to create elements that are not affected by the same attributes and properties as those in the Light DOM. The Shadow DOM provides true scope encapsulation; your element’s CSS and JS are scoped to it alone! Think of the Shadow DOM as a lightweight version of an iframe.
To render elements created via the Shadow DOM, you must ‘inject’ them into the Light DOM. We’ll cover some examples of this later in the post.
You have already seen the Shadow DOM
The most common example is the Video Tag. Take this simple example tag:
This simple tag results in the following rendered HTML in your browser:
Notice how much “extra” HTML is rendered under the “#shadow-root”. This code is generated by your browser automatically to give you these complex UI elements like the Play Button and the Volume Slider.
These elements have their own styling and event listeners that are not affected by the host DOM.
Why should we care about the Shadow DOM?
Using the Shadow DOM you can create truly re-usable pieces of code you know will act reliably no matter where you place them. Create one widget, and use it in any of your code, and stop worry about CSS and JS collisions!
Also, most importantly, the Shadow DOM is the base from which the modern web is being built upon.
When we talk about web components, we are talking about the implementation of the Shadow DOM. When you see those fancy ‘live’ updating forms in Angular2, again, Shadow DOM.
Clearly, understanding this is quite important to understanding these new web frameworks.
Example 1: Inserting Elements into a Host Root
Here is a very basic example illustrating using the Shadow DOM to inject elements into a host root.
Example 2: Isolated styles in a Shadow DOM Element
Here is a very basic example showing the isolated CSS styling when using the Shadow DOM.
Please note the injected element’s CSS does not affect the CSS in the host element. Only the injected elements are red.
Example 3: Insertion Points with “content” tags
Here is an example showing insertion points and querying using the content tag. (Please note, that in Shadow DOM v1, the content tag will be replaced by the slot selector, read more about this below in “Whats Next”)
This simple example shows how one can select some content from the host element, inject it into the Shadow DOM template, which in turn get injected into the host DOM.
We reviewed some concepts about the Shadow DOM laid out in what is commonly referred to as “Shadow DOM v0”. This is to say we are working with the very first iteration of the implementation.
The new spec for v1 has, for the most part, been agreed upon and the major browser publishers are working on implementing the new features.
Hayato Ito at Google has a great list explaining some of the changes we can expect along with simple examples showing these new features.
While I provided only simple examples of the Shadow DOM, I hope this inspires you to explore more yourself. Thanks for reading!
How it Works
TypeScript is just a superset of JS that compiles to ES3, ES5 or ES6. Think of this as a higher level language that normalizes the features of ES5 & ES6 into a version compatible with your target language and polyfills missing features.
This means, if you are compiling to ES3, TS will turn your fancy ES6 class into the syntactic sugar required to replicate it in ES3. Also, it will do it better than you.
Why TypeScript is a good thing: you can have ES6 features, now
ES6 compatibility is woefully lacking for most browsers found in the wild, which is definitely appealing if you want to use some of those cool features you hear about… especially the ones that most people gripe about the lack of in JS (classes and inheritance) when compared to most other OOP languages.
Classes and Modules are now available to you, and down compiled . You can use the super cool (and often confusing on your first encounter) “arrow” functions notation for your Anonymous Functions. Rest functions where you can finally make your functions as flexible as you want them.
When you let TypeScript transpile your code you can have all of those amazing ES6 features with your current user base’s browsers! Yes, even Safari!
Why TypeScript is a good thing: You get type hints, type checking at compile time
Type annotations allow you to specify the exact type of input and output you are passing around your functions. This not only leads to implicit assertions of your types, but also allows for great real-time syntax checking if you are using an editor that supports it.
Also, the next time you try and pass a boolean variable to a function expecting a string, your compiler will complain “LOUDLY” and refuse to compile your crap code. Using explicit variable types is the best documentation you can provide and its built into the code you are writing.
How to Install / Use It
Install TSC via NPM
npm install -g typescript
Then follow along in the easy to understand QuickStart / HelloWorld from the TS team: http://www.typescriptlang.org/docs/tutorial.html
If you cannot install it, you can also try the TS playground: http://www.typescriptlang.org/docs/tutorial.html
Who is really using TypeScript?
Well, for one, Microsoft is using it on quite a few internal projects. The Angular 2 team actually wrote the majority of the new framework using TypeScript. Also, the popular project management tool Asana’s team made a rather well publicized switch to TypeScript recently.
Should I use TypeScript?
The simple answer is, sure. Why not. I would give it a shot and try and work it into your workflow and see how it goes. Thankfully it plays nice with vanilla JS as well.
Leave us a note in the comments if you actually use TypeScript, or have a good reason not to use TypeScript, in your work.
In our previous posts, we discussed how to use some tools to explore and debug legacy code. This blog post will explore one of these tools that I personally use quite often in depth: Xdebug and Remote Debugging.
We’ll explore the installation, the required settings tweaks, and some basic tools and workflows to get you started. The least fun and hardest part of this whole process is the installation.
Having xdebug up and running will speed up your code investigations and will really help you dig into troublesome code. It will also give you the best insight into code you aren’t familiar with works without resorting to die statements and var_dumps for small windows.
Please only install this on your development and staging environments! Do not install this on any public facing server!
I want to take a minute and explain the concept of remote debugging with Xdebug. Until a few years ago, I would install XDebug only to get the “pretty error printing” features. While these features allowed some better control over how I was viewing errors and my var_dump results, it really added nothing I critically needed. Remote debugging now makes XDebug a short list of ‘need to install’ things when setting up a new environment.
Xdebug offers mechanisms to allow you to set breakpoints in your code to stop it’s execution and view the current state. This means you can say “stop here and let me take a look around at what the code is doing at this moment” on the server itself. You actually connect to the server and can poke around, set some conditional break points (where you stop execution when a variable is set to a certain value) and even evaluate some raw PHP on the server given certain conditions.
To accomplish this, you must connect a debugging tool to your server with a specified and exposed port and talk to it using a protocol provided by XDebug. Your debugger is the tool you use on your machine, XDebug is the tool/port/settings collection you use to connect to your server.
If this sounds like the basic IDE debugging tools you have used with other languages like C++ and JAVA (and also like something overcomplicated for being such a normal feature for other development stacks), it should. It’s pretty much the same thing. The biggest difference here is that this was not a widely used debugging method for hosted PHP. I’d like to help change that with this blog post.
Installing the Xdebug Extension
The xdebug project and github page offer some installation instructions that feel woefully lacking. Also, they offer little advice tailored to individual setups and environments. I’ll try and provide some examples of common installation methods.
Please note that these methods assume you are installing on the same server you host your development environment that serves the PHP code you wish to debug. This means, if you are running a vagrant box or docker container to host your code, install xdebug on this server instance. If you host your locally code on the same machine you are edit and maintain the code on, install xdebug on this machine. See the section above for some clarification on remote debugging.
All of these instruction assume you have administrator access and some level of comfortability with the *unix command line. If you do have access to your server in this capacity, or you are not comfortable with running these commands, you might want to find a grown up to help you.
pecl / pear
You can install Xdebug extension with the pecl tool and then tweak your php.ini file to include the installed extension. The official docs recommend this route first actually. The installation instructions are the same with the pear tool as they are for pecl. I have found this is the easiest installation method if you are running your server on a MacOS environment.
After you are sure you have pecl installed, run this command on your command line.
pecl install xdebug
apt-get / yum
If you are running your server on an Ubuntu/Debian/CentOS machine, you can install the xdebug with your specific package manager.
sudo apt-get install php5-xdebug
yum install php5-xdebug
This is a method I have never tried personally but I know there are some recipes specifically for installing xdebug with homebrew.
From what I read, you will need to add the homebrew-php repository and install this from the command line as well. Check out this repo link for more information.
Compiling it yourself
Another method I have never tried personally, but I know its possible. If you are want to do this yourself, you might be beyond the scope of this post. I’ll just point you to the project page for the most up to date information.
Update your php.ini file
Find your newly installed php extension and add this line to your php.ini file
Replace the “xdebug.so” file with whatever your tool installed. It’s also safe to create a symlink with the filename “xdebug.so” as well. If you have trouble finding this file, try the following command to find the extension file:
find / -name ’*xdebug*.so’ 2> /dev/null
Verifying your XDebug Installation
Restart apache and create a test file called test.php with the following lines of code and load it into your browser:
Search for “xdebug” and you should see something like this in your browser:
If you see a line that looks like the one highlighted above, congrats, you have installed xdebug!
You will need to expose some ports on your server to allow connections from your debugging client. How you accomplish this will certainly depend on your individual environment setup, but I would like to note this to save you the time I lost trying to find out why I could not connect.
And we will explain the port you will need to be expose and forward in this next section…
Xdebug INI Settings
Here are some of the INI settings you will need to update in order to enable remote connections. These settings will be found in your php.ini file, or a possible xdebug.ini file if one was created by your install method.
This setting allows you to specify an address where you debugging client is connecting from.
In most cases, this will be set to “localhost”, but may differ in your development environment.
This setting is ignored if xdebug.remote_connect_back is set to TRUE. See more info below.
This setting enables remote debugging, turn this on!
This setting allows you to specify a port for your debug client to connect to the remote server with. You will need this value when configuring your remote debugging tool.
This is typically set to 9000 but you can update this to any port that isn’t being used if you feel contrary.
This setting allows you to specify the amount of array children and object’s properties are shown when you use a var_dump or use your debugging client’s function trace tool.
By default this is set to 128, but you can set it to -1 if you want to remove the limit entirely.
Like var_display_max_children, this setting allows you to set a maximum string length that is shown when variables are displayed in var_dumps or function traces.
By default this is set to 128, but you can set it to -1 if you want to remove the limit entirely.
Another setting that allows you to set a limit when using var_dump or function tracing, but this one sets the nested levels of array elements and object properties displayed.
By default, this is set to 128, but again if you live dangerously you can remove the limit entirely and set it to -1.
Setting this value to true will disable the @ (the “shut up”) operator entirely.
This is super useful when you find out when you predecessor was just hiding a critical error behind the @ operator and you can finally go to be because you found the elusive notice showing the variable was never set in the first place and you had no idea and thats why you can’t get the page to load when you don’t have a cookie set in IE 9.
Setting this value to true will allow you to connect and attach a remote debugging client to your server from any address.
This setting is great for shared development environments but is quite dangerous since it will just allow anyone to connect who tries. YES, anyone.
Also of note, this will override the xdebug.remote_host setting.
While I personally like to use the stand alone tools, I do know a lot of people who prefer to use these editors to remote debug.
While I’m sure a cursory google search can lead you to some better instructions on how to install and configure these tools, I thought it was worth mentioning since a lot of people use these tools and they offer the remote debugging tools you might want to use.
This is a tool I use on an almost daily basis. Its relatively small and lightweight, and gets out of the way when I am done. I also mentioned it in our last blog post. I do need to note that this tool does not seem to be updated frequently and occasionally crashes without warning. That being said, I still highly recommend it.
All of us will encounter legacy code, and most of us will ‘inherit’ code to maintain. In our first post on legacy code, we talked about getting the things you need to start working on a project. In this post, we will talk about how you can evaluate the backend code you will most likely have to start digging in to start new features or squashing bugs.
While you will encounter a significant amount of UX or front-end issues when starting on a new project, you are also just as likely to have to track an issue to the underlying backend code. The backend not only creates the foundation for your web app but its also the last line of defense for your back end code. At minimum issues on the backend will cause confusing results or headaches. At worst, issues on the backend will expose some of the most vital parts of your webapp to exploits.
Most backend code is the result of a lot of hours and hard work; it can be extremely confusing to wrap your head around the basic concepts let alone the deeper portions of the code. We’ll discuss some basic patterns and explain some of the tools we use to explore code, PHP code in particular, when we take on a project with some ‘baggage’.
I like to split the application into small semantic sections. You can either break an application down into ‘workflows’, the actions a user may perform with an application; or as ‘roles’, things a particular actor will use a web app for. While this may sound like a very high level activity for inspecting back end code I think its crucial for understanding the application itself.
Once you have split the code into sections, trace the entire workflow. Follow the code from the beggining of an action to the resulting output. Tracing through the code will allow you to completely understand it.
Debugging and Tracing Tools
This is one of my favorite tools and is the first thing I install when I set up a new environment. Not only does this give me much easier to read error outputs, but it also gives you some great tools for interactive debugging. Seriously, if you do nothing else I suggest, at least install xdebug.
Interactive debugging is the best tool for finding that super stubborn bug or finding out why something isnt working as you expect. With a remote interactive debugger you can set break points and view exactly what the code is doing at a given point in time. You can actually inspect a variable value and watch it change as you step through the lines of code. This is something you should get excited about. Check out the screenshot below to see this in action with an example Erdiko project:
I use MacGDBp, a Cocoa based debugging tool that allows you to set break points and view the code when you set break points. I’ve been told that PHPStorm and even Sublime have some interactive debugging tools, I have not used those. MacGDBp is a bit dated, and I think almost abandonware, but it is still an indispensible tool in my aresenal. Check out the MacGDBp project docs for more info about the feature set and how to install it.
Personally, I would recommend using MacGDBp along with xdebug and the chrome extension ’chrome-xdebug-enabler’ to interact with your debugger. Using this extension you can conditionally turn the debugging off and on as you wish when refreshing the page.
I should note that while I personally use MacGDBp with vim, many other editors also include some remote debugging tools. PHPStorm has this functionality built in, but there are plugins for SublimeText and other full editors. We will explore those in a later post.
PHPLint and PHPCodesniffer
There are two great tools for getting some high level information about a PHP codebase: PHPLint and PHPCodesniffer.
PHPCodesniffer evaluates code based on a provided set of rules and standards and outputs a report that can give you a good idea of how ‘bad’ things look under the hood. It’s actually two tools: phpcs and phpcbf. phpcs evaluates the code, phpcbf attempts to fix the code. Personally, I like to use some discretion when tweaking code, so I would reccomend using phpcbf sparingly.
PHPLint is another tool, very similar to PHPCS that also outputs information on a code base based on rules and validation sets. This one is also very useful for generating user docs based on docblocks. This can be EXTREMELY useful when you need to collect a lot of information about a large codebase and create some baseline documentation for your team.
Unit testing is often touted as the best prevention of introducing new bugs and finding conflicting code. I would also like to note, most people ignore the fact that introducing unit testing to legacy code is a painful process. Code written without testing in mind can often be a pain to manage dependencies and ‘magically’ required code.
This is a topic that actually deserves its own blog post, but I do want to mention it in this one.
… to be continued
In my next post, ill include some instructions on how to install xdebug on your local *nix development environment.
All of us will encounter legacy code, and most of us will ‘inherit’ code to maintain. Even on the freshest of projects 99 % of the time you will encounter some ‘baggage’ code that we will have to maintain. This is especially true as a contractor for any PHP project. Deservedly or not, PHP has a bad reputation for code quality
The good news is that you can mitigate some of the worst aspects of a legacy project by doing some work up front. Making sure you have all the assets you need up front can prevent embarrassing emails to the client asking for random things and generally making your life easier.
For this first of three blog posts about legacy code, we’ll spit this into two lists: Things you need and nice to haves.
Things you need:
This should be a no brainer. You need access to the server to make sure you have the most up to date code, and hopefully you will be deploying some updates in the near future. Yes, this may seem very obvious but you would be surprised how easy it is to forget this step in the excitement of a new project.
Ask the client how they access and how the previous team accessed the server. Make sure you try and actually login with these credentials as well. After you successfully get access, you may need to deactivate or in the minimum change some passwords of the previous server users.
Code in Version Control
You will also want access to the most up to date version of the codebase, hopefully in a form of version control. Again, while this seems like a no-brainer, it is very important to track changes you make once you start to dig into the code. It can also provide some information as to what the previous developer was thinking with the code in the past.
Once you have access to this you can convert it to your VCS of choice or continue to use the one provided. You will really want to consider keeping the VCS the same if you are working with other existing teams or with the client who needs access to the code.
It is also worth your time to ensure that the code in the VCS is sync’d and up to date with what is on the production server. There are many file comparison tools that can be used to compare entire directories which we will cover in our next post. While you can assume a previous team who had a code base in version control has kept things up to date… like the Russians say: Trust, but verify.
Ask for any documentation the client can provide, good or bad. Something is better than nothing.
You should also plan on converting this into some form of living document you can edit and share easily. A self hosted wiki works great for tracking changes, but so does a markdown file stored in the repo itself. Anything easy to edit will remove another barrier that will prevent you from updating documentation, and already loathsome task.
You should be documenting everything as you explore the project. Document the file and database structure, document the existing workflows. Ask the client how things “should work” and then note how things are broken. Get it all into a living document so you can track your progress.
Nice to Haves:
A Shared Project Management System
Create a method in which you can communicate your project status with the customer. This will also provide a great resource in which you and the client can document bugs and future updates.
A shared system will allow you to manage your project beyond instant messages and emails. It also provides instant feedback to the client allowing them to see ‘exactly what they are paying you for’ and allows for the easier exchange of ideas.
If you’re lucky, the client may already have one (and be trained on how to use it.) It’s also very likely the client does not know how or what a Project Management System is, in which case priority number one is showing them how it is useful.
A separate Staging and local development environment
Tools like Docker and Vagrant allow you to spin up servers quickly and provide tools to re-recreate the server after you mess it up. This will become very important as you dig in and mess things up while trying to determine exactly what is wrong.
Our next post will focus on some frameworks and tools we commonly use to evaluate legacy code. We’ll also provide some basic examples of how to use these tools.
The AJAX paradigm really launched the web into primetime some 10+ years ago, but now its almost expected. Now it’s a ubiquitous part of the web landscape. Most web apps now resemble an ‘app’ in regards to their UX and users ‘expect’ content to dynamically update without a page refresh. In the past, we have used some great tools like jQuery to cobble together a basic app to interact with our page and an AJAX backend, but a framework like AngularJS adds some sanity and structure to what could have been a mess of spaghetti code.
The most common use cases for AJAX are dynamic content and form interactions. For example, if you have a large list of tabular data, you can load it via AJAX to show your basic page to a user without having to render the table on the server. Forms can be validated with JS and sent to the server in the ‘background’ so the user doesn’t have to leave the page. There are MANY other use cases for AJAX, but I think this covers the majority you will encounter when developing a web app.
HTTP / XHR
Most browsers you will encounter, or your clients will use, will have access to the HTTP API known as XHR (it’s safe to assume that anything above IE 5.6 will allow you access to this API). While some browsers offer Fetch support, I will skip that for the purposes of this blog post.
In general, you will provide AJAX access via a service. Services are a part of the Dependency Injection patten that makes AngularJS so modular. Creating a piece of code that allows you to encapsulate all actions that make AJAX calls allows for better re-use and easier testing.
Observables vs Promises
Too often used tools/patters for working with asynchronous data structures are Observables and Promises. While you may be familiar with Promises as a pattern, and most likely have used something like promises in the past, Observables are a pretty new concept to me.
In short, Observables are “a push based collection” using the observer pattern. Put simply, this is a queue of objects with some amazing manipulation methods and hooks to allow you to detect when something occurs within the queue. It’s pretty great for dealing with a dataset that needs to be lazy loaded or can possibly get updated in the life cycle of the application.
Here is a simple example based on the angular.io Hall of Heros example showing an observable request:
A promise is “a way to define actions or computations once an async event completes”; an observable is “way to define computations or actions that happen when one or more events in a stream occur”.
Here is a simple example based on the angular.io Hall of Heros example showing an promise based request:
The key take away from comparing these two tools: observables and promises are both great tools for async programming like AJAX, but observables are more like a stream of data than a ‘one time request of data’. We’ll touch more on this in future blog posts.
Here are some code examples that borrow very heavily from the HTTP Client example found on the Angular.io site.