This days I working a lot with AngularJs applications (who doesn’t?). Normally my backend is a Silex application. It’s pretty straightforward to build a REST api with Silex. But when we play with an AngularJs client we need to face with a a problem. POST requests “doesn’t” work. That’s not 100% true. They work, indeed, but they speak different languages.
Silex assumes our POST requests are encoded as application/x-www-form-urlencoded, but angular encodes POST requests as application/json. That’s not a problem. It isn’t mandatory to use one encoder or another.
For example
name: Gonzalo
surname: Ayuso
If we use application/x-www-form-urlencoded, it’s encoded to: name=Gonzalo&surname=Ayuso
And if we use application/json, it’s encoded to: { "name" : "Gonzalo", "surname" : "Ayuso" }
It’s the same but it isn’t.
Imagine this Silex example.
[sourcecode language=”php”]
use Silex\Application;
use Symfony\Component\HttpFoundation\Request;
This example works with application/x-www-form-urlencoded but it doesn’t work with application/json. We cannot use Symfony\Component\HttpFoundation\Request parameter’s bag as usual. We can get the raw request body with:
In this post we’re going to enclose this code within a service provider. OK, that’s not really a service provider (it doesn’t provide any service). It just change the request (when we get application/json) without copy and paste the same code within each project.
[sourcecode language=”php”]
use Silex\Application;
use G\AngularPostRequestServiceProvider;
use Symfony\Component\HttpFoundation\Request;
$app = new Application();
$app->register(new AngularPostRequestServiceProvider());
Last days I’ve been playing with OpenUI5. OpenUI5 is a web toolkit that SAP people has released as an open source project. I’ve read several good reviews about this framework, and because of that I started to hack a little bit with it. OpenUI5 came with a very complete set of controls. In this small example I want to use the “table” control. It’s just a datagrid. This days I playing a lot with Angular.js so I wanted to use together OpenUI5’s table control and Angularjs.
I’m not quite sure if it’s a good decision to use together both frameworks. In fact we don’t need Angular.js to create web applications using OpenUI5. OpenUI5 uses internally jQuery, but I wanted to hack a little bit and create one Angularjs directive to enclose one OpenUI5 datagrid.
First of all, we create one index.html. It’s just a boilerplate with angular + ui-router + ui-bootstrap. We also start our OpenUi5 environment with de default theme and including the table library
And now we can create a simple Angular.js using the ng.openui5 module. In this application we configure the table and fetch the data from an externar API server
Today an original post. Maybe I’m the only one doing this, I know. 2014 is close to finish and I want to review how it went the year. Let’s start.
The bad parts:
My book about SOLID principles (in Spanish) isn’t released yet. It’s almost finished. It only needs a few reviews, but because one thing or another it looks like it isn’t be released this year. Lesson learned: Those kind of side projects must have a release date. If they haven’t, another side projects can grab our attention and they can be frozen.
No new languages learned this year. There was a good chance with Swift. A new language, but it didn’t attract my attention. Erlang books are still in my desk and also my aim to improve my Java skills didn’t success. I found nothing where apply my Java learning.
The good parts:
Finally I can say JavaScript is a first class language within my personal software stack. Various projects with JS this year and I feel very comfortable writing JavaScript code. That’s also the year of Angular.js (for me and probably a lot of people).
This year has been the year of mobile development for me. I’ve been involved with several projects using Cordova/Phonegap framework. I the beginning to install Cordova environment, compile, deploy the application into the device was something “heroic” but now it turns into trivial operations. I still remember my beginning with jQuery Mobile. Horrible. Then I started using Angular.js and Topcoat. Much better, but still problems when switching between Android and IOs. Finally I re-discover Ionic framework. Incredible project. Hybrid applications with angular.js with very complete toolkit. This year has been crowed by push notifications, camera plugins, barcode scanners, token based authorisations, Websockets and things like that. Now hybrid applications with Phonegap/Cordova live in my comfort zone along with Silex, Angular, PHP… (that’s means I need to find other places outside it)
The last part of the year I’ve been working a lot with automation tools: Bower and Grunt mainly. I also started to work with JavaScript testing with Karma and Jasmine
This year I’ve been a proud speaker at DeSymfony Day in Barcelona. On incredible weekend. Meeting with colleagues, speaker dinner, great conversations, and tourism in a great city. Definitely the most beautiful room for a conference that I ever been
Katayunos The coding dojo where we play with TDD and Pair Programming is still alive. Maybe not as continuous as I’d like, but we still meet together 20-25 people one Saturday morning to improve our programming skill, from time to time
My personal blog is still alive too. It’s close to be 5 years old (OK, technically speaking 6, but first year it wasn’t a serious one). More than 20k views per month and sometimes close to 30k (Hey, thank you for reading!)
And that’s all. It was a good year. Hopefully it will be worse than 2015 🙂
I really like WebSockets. I’ve written several posts about them. Today we’re going to speak about something related to WebSockets. Let me explain it a little bit.
Imagine that we build a Web Application with WebSockets. That’s means that when we start the application, we need to connect to the WebSockets server. If our application is a Single-page application, we’ll create one socket per application, but: What happens if we open three tabs with the application within the browser? The answer is simple, we’ll create three sockets. Also, if we reload one tab (a full refresh) we’ll disconnect our socket and reconnect again. Maybe we can handle this situation, but we can easily bypass this disconnect-connect situation with a HTML5 feature called SharedWorkers.
Web Workers allows us to run JavaScript process in background. We also can create Shared Workers. SharedWorkers can be shared within our browser session. That’s means that we can enclose our WebSocket server inside s SharedWorker, and if we open various tabs with our browser we only need one Socket (one socket per session instead one socket per tab).
I’ve written a simple library called gio to perform this operation. gio uses socket.io to create WebSockets. WebWorker is a new HTML5 feature and it needs a modern browser. Socket.io works also with old browsers. It checks if WebWorkers are available and if they isn’t, then gio creates a WebSocket connection instead of using a WebWorker to enclose the WebSockets.
We can see one simple video to see how it works. In the video we can see how sockets are created. Only one socket is created even if we open more than one tab in our browser. But if we open a new session (one incognito session for example), a new socket is created
Here we can see the SharedWorker code:
[sourcecode language=”js”]
"use strict";
importScripts(‘socket.io.js’);
var socket = io(self.name),
ports = [];
addEventListener(‘connect’, function (event) {
var port = event.ports[0];
ports.push(port);
port.start();
port.addEventListener("message", function (event) {
for (var i = 0; i < event.data.events.length; ++i) {
var eventName = event.data.events[i];
socket.on(‘connect’, function () {
for (var i = 0; i < ports.length; i++) {
ports[i].postMessage({type: ‘_connect’});
}
});
socket.on(‘disconnect’, function () {
for (var i = 0; i < ports.length; i++) {
ports[i].postMessage({type: ‘_disconnect’});
}
});
[/sourcecode]
And here we can see the gio source code:
[sourcecode language=”js”]
var gio = function (uri, onConnect, onDisConnect) {
"use strict";
var worker, onError, workerUri, events = {};
function getKeys(obj) {
var keys = [];
for (var i in obj) {
if (obj.hasOwnProperty(i)) {
keys.push(i);
}
}
return keys;
}
function onMessage(type, message) {
switch (type) {
case ‘_connect’:
if (onConnect) onConnect();
break;
case ‘_disconnect’:
if (onDisConnect) onDisConnect();
break;
default:
if (events[type]) events[type](message);
}
}
function startWorker() {
worker = new SharedWorker(workerUri, uri);
worker.port.addEventListener("message", function (event) {
onMessage(event.data.type, event.data.message);
}, false);
worker.onerror = function (evt) {
if (onError) onError(evt);
};
I’ve also created a simple webSocket server with socket.io. In this small server there’s a setInterval function broadcasting one message to all clients per second to see the application working
[sourcecode language=”js”]
var io, connectedSockets;
Remember my last post about WebSockets and AngularJs? Today we’re going to play with something similar. I want to create a key-value interface to play with websockets. Let me explain it a little bit.
First we’re going to see the backend. One Silex application with two routes: a get one and a post one:
[sourcecode language=”php”]
<?php
include __DIR__ . ‘/../../vendor/autoload.php’;
include __DIR__ . ‘/SqlLiteStorage.php’;
use Silex\Application;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Silex\Provider\DoctrineServiceProvider;
interface StorageIface
{
public function get($key);
public function post($key, $value);
}
[/sourcecode]
Our implementation uses SqlLite, but it’s pretty straightforward to change to another Database Storage or even a NoSql Database.
[sourcecode language=”php”]
use Doctrine\DBAL\Connection;
use G\Io\Storage\StorageIface;
class SqlLiteStorage implements StorageIface
{
private $db;
public function __construct(Connection $db)
{
$this->db = $db;
}
public function get($key)
{
$statement = $this->db->executeQuery(‘select value from storage where key = :KEY’, [‘KEY’ => $key]);
$data = $statement->fetchAll();
If you work with in-house iOS applications you need to define a distribution strategy (you cannot use Apple Store, indeed). Apple provides documentation to do it. Basically we need to place our ipa file in addition to the plist file (generated when we archive our application with xCode). I’m not going to explain how to do it here. As I said before it’s well documented. Here I’m going to explain how to do the same trick than the Android’s post but now with our iOS application.
With iOS, to install the application, we only need to provide the iTunes link to our plist application (something like this: itms-services://?action=download-manifest&url=http://url.to.plist) and open it with the InAppBrowser plugin.
We can use exactly the same angularJs used the the previous post to check the version and the same server-side verification.
We also can detect the platform with Device plugin and do one thing or another depending on we are using Android or iOS.
Here you can see one example using ionic framework. This example uses one $http interceptor to send version number within each request and we trigger ‘wrong.version’ to the event dispatcher when it detects a wrong versions between client and server
The last May I attended to the great deSymfony day conference in Barcelona. At speaker’s dinner I had a great conversation with Máximo Cuadros about Dependency Injection Containers. We discuss about the customisation of containers. I said that I prefer Symfony´s DIC instead of Pimple, mainly because its configuration with YAML (or even xml) files. But In fact we can customise Pimple/Containers with YAML files in a similar way than we do it with Symfony’s DIC. In this example we’re going to see one way to do it.
We can easily extend the Pimple/Container and add a function to load a YAML files, parse them and build the container. But doing this we’re violating various SOLID principles. First we’re violating the Open-Close principle, because to extend our Pimple/Container with the new functionality we are adding new code within an existing class. We’re also violating the Dependency Inversion Principle and our new Pimple/Container is going to be harder to maintain. And finally we’re obviously violating the Single Responsibility Principle, because our new Pimple/Container is not only a DIC, it’s also a YAML parser.
There’s another way to perform this operation without upsetting SOLID principles. We can use the Symfony’s Config component
The idea is simple. Imagine this simple application:
[sourcecode language=”php”]
use Pimple\Container;
$container = new Container();
$container[‘name’] = ‘Gonzalo’;
$container[‘Curl’] = function () {
return new Curl();
};
$container[‘Proxy’] = function ($c) {
return new Proxy($c[‘Curl’]);
};
$container[‘App’] = function ($c) {
return new App($c[‘Proxy’], $c[‘name’]);
};
As we can see we’re using a similar syntax than Symfony’s DIC YAML files.
Now, with our new library we can use the following code:
[sourcecode language=”php”]
use Pimple\Container;
use G\Yaml2Pimple\ContainerBuilder;
use G\Yaml2Pimple\YamlFileLoader;
use Symfony\Component\Config\FileLocator;
$container = new Container();
$builder = new ContainerBuilder($container);
$locator = new FileLocator(__DIR__);
$loader = new YamlFileLoader($builder, $locator);
$loader->load(‘services.yml’);
Now our Pimple/Container is just a Pimple/Container nothing more. It doesn’t know anything about yaml, parsers and thing like that. It’s doesn’t have any extra responsibility. The responsibility of the parser falls on YamlFileLoader
You can see the library in my github account. It’s but one usage example of Symfony’s Config component. It only allows Yaml files, but it can be extended with Xml files adding a XmlFileLoader.
Angular creates one $scope object for each controller. We also have a $rootScope accesible from every controllers. But, can we access to one controller’s $scope from another controller? The sort answer is no. Also if our application needs to access to another controller’s $scope, we probably are doing something wrong and we need to re-think our problem. But anyway it’s possible to access to another controller’s $scope if we store it within a service. Let me show you and example.
And now we need to store the $scope in the service:
[sourcecode language=”js”]
app.controller(‘OneController’, function ($scope, Scopes) {
Scopes.store(‘OneController’, $scope);
…
});
app.controller(‘TwoController’, function ($scope, Scopes) {
Scopes.store(‘TwoController’, $scope);
…
});
[/sourcecode]
$scope.buttonClickOnOneController = function () {
Scopes.get(‘OneController’).buttonClick();
};
});
app.factory(‘Scopes’, function ($rootScope) {
var mem = {};
I’m a big fan of websockets. I’ve got various post about them (here, here). Last months I’m working with angularjs projects and because of that I wanna play a little bit with websockets (with socket.io) and angularjs.
I want to build one angular service.
[sourcecode language=”js”]
angular.module(‘io.service’, []).
factory(‘io’, function ($http) {
var socket,
apiServer,
ioEvent,
watches = {};
The idea of the application is to watch one model’s variable (‘question’ in this example) and each time it changes we will send the value to the websocket server and we’ll so something (we will convert the string to upper case in our example)
As you can read in one of my previous post I don’t like to send messages from the web browser to the websocket server directly (due do to authentication issues commented here). I prefer to use one server (a Silex server in this example)
[sourcecode language=”php”]
include __DIR__ . ‘/../../vendor/autoload.php’;
use Silex\Application;
use Symfony\Component\HttpFoundation\Request;
$app = new Application([‘debug’ => true]);
$app->register(new G\Io\EmitterServiceProvider());
$app->get(‘/request’, function (Application $app, Request $request) {
Maybe this post can be obvious but I’ve spoken about it with various developers who don’t know it. It really improves the developing process of cordova/phonegap apps with android at least for me.
With android we can see the log with “adb logcat” but it’s a nightmare. Huge amount of information about our app and also about the operating system. If we’re grep ninjas we can handle it, but as well as I’m not a ninja I prefer another solution. Do you know “chrome://inspect/”? If not, have a look as soon as possible to this tool. We can see the browser’s console of our android in our desktop browser. We only need to enable “usb remote debugger” within our android device and plug with a USB cable. Chrome will detect the remote browser and we can see the console in the same way than we see it when we use Chrome locally.
But we’re speaking about cordova/phonegap apps here so, what we need to do to use chrome://inspect with our hybrid apps? The answer is simple: we don’t need to do anything. Cordova applications is nothing than a Webkit browser inside a native app. Chrome es Webkit too so chrome://inspect will detect our remote device app and we will open console.
This small trick in addition to the last post really marks a before and an after at least in my developing process.
If our app crashes in the device we only need to see the console’s log within our browser and see what happens. We also can add functionality, change variables, and override functions in the same way than we do it with our local browser.