SlideShare a Scribd company logo
Symfony2 and AngularJS
Antonio Perić-Mažar
16.05.2014, PHPday Verona
https://joind.in/talk/view/11290
About me
• Antonio Perić-Mažar,
mag. ing. comp.
• CEO @ locastic
• Software developer, Symfony2
• Sylius Awesome Contributor :)
• www.locastic.com
• antonio@locastic.com
• twitter: @antonioperic
Who we are?
• locastic (www.locastic.com)
• Web and mobile development
• UI/UX design
• Located in Split, Croatia
Our works?
Symfony2 and AngularJS
Symfony2
 PHP Framework, server side
 MVC, HTTP
 Toolbox, methodology
 One of the most advanced PHP framework
 Strong community
 Easy to test it
Symfony2
 Bundles
 Components
 Routing
 Templating (Twig)
 Forms
 etc
AngularJS
 Client-side JavaScript framework
 Prescriptive, MVC (MVVM)
 Makes creating UI easier thought data-binding
 Good organizing and architecture
 Learning curve, easy to start hard to master
 $scope, modules, controllers, providers, services
AngularJS Core
Two-way data binding
JS:
<span id=”someId”></span>
document.getElementById('someId').text = 'locastic';
NG
<span>{{someName}}<span>
var someName = 'locastic';
AngularJS Core
<html ng-app>
<head>
<script src=”angular.js”></script>
<script src=”controller.js”></script>
<head>
<body>
<div ng-controller=”HelloController”>
<p>{{ greeting.text}}, World</p>
</div>
</body>
</html>
// controller.js
function HelloController($scope) {
$scope.gretting = {text: 'Hello'}
}
HTML template
AngularJS Core
 Deep Linking
 Dependency Injection
 Directives
<div class=”container”>
<div class=”inner>
<ul>
<li>Item
<div class=”subitem”>Item2</div>
</li>
</ul>
</div>
</div>
<dropdown>
<item>Item 1>
<subitem >Item 2</subitem>
</item>
</dropdown>
+
SPA (Singe Page App)
SPA
 Aka SPI (Single Page interface)
 desktop apps UX
 HTML / JS / CSS / etc in single page load
 fast
 AJAX and XHR
Symfony2 and AngularJS
SPA Arhitecture
Backend (rest api) with Symfony2
Frontend with AngularJs
Separation or combination?
UI == APP
Symfony2 AngularJS
Usage, language Backend, PHP Frontend, Javascript
Dependency Injection Yes Yes
Templating Twig HTML
Form component Yes Yes
Routing component Yes Yes
MVC Yes Yes
Testable Yes Yes
Services Yes Yes
Events Yes Yes
i18n Yes Yes
Dependency management Yes Yes
RESTful ws
Simpler than SOAP & WSDL
Resource-oriented (URI)
Principles:
HTTP methods (idempotent & not)
stateless
directory structure-like URIs
XML or JSON (or XHTML)
Building Rest Api with SF2
There is bundle for everything in Sf2. Right?
So lets use some of them!
Building Rest Api with SF2
What we need?
JMSSerializerBundle
FOSRestBundle
NelmioApiDocBundle
Building Rest API with SF2
JMSSerializerBundle
(de)serialization
via annotations / YAML / XML / PHP
integration with the Doctrine ORM
handling of other complex cases (e.g. circular references)
Building Rest Api with SF2
LocasticBundleTodoBundleEntityTodo:
# exclusion_policy: ALL
exclusion_policy: NONE
properties:
# description:
# expose: true
createdAt:
# expose: true
exclude: true
deadline:
type: DateTime<'d.m.Y. H:i:s'>
# expose: true
done:
# expose: true
serialized_name: status
Building Rest Api with SF2
fos_rest:
disable_csrf_role: ROLE_API
param_fetcher_listener: true
view:
view_response_listener: 'force'
formats:
xml: true
json: true
templating_formats:
html: true
format_listener:
rules:
- { path: ^/, priorities: [ html, json, xml ], fallback_format: ~, prefer_extension: true }
exception:
codes:
'SymfonyComponentRoutingExceptionResourceNotFoundException': 404
'DoctrineORMOptimisticLockException': HTTP_CONFLICT
messages:
'SymfonyComponentRoutingExceptionResourceNotFoundException': true
allowed_methods_listener: true
access_denied_listener:
json: true
body_listener: true
Building Rest Api with SF2
/**
* @ApiDoc(
* resource = true,
* description = "Get stories from users that you follow (newsfeed)",
* section = "Feed",
* output={
* "class" = "LocasticBundleFeedBundleEntityStory"
* },
* statusCodes = {
* 200 = "Returned when successful",
* 400 = "Returned when bad parameters given"
* }
* )
*
* @RestView(
* serializerGroups = {"feed"}
* )
*/
public function getFeedAction()
{
$this->get('locastic_auth.auth.handler')->validateRequest($this->get('request'));
return $this->getDoctrine()->getRepository('locastic.repository.story')->getStories($this->get('request')-
>get('me'));
}
Building Rest Api with SF2
Templating
TWIG <3
Templating
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>{% block title %}Welcome!{% endblock %}</title>
{% block stylesheets %}
<!-- Place favicon.ico and apple-touch-icon.png in the root directory -->
{#<link rel="stylesheet" href="{{ asset('css/normalize.css') }}">#}
<link rel="stylesheet" href="{{ asset('css/main.css') }}">
<!-- load bootstrap and fontawesome via CDN -->
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" />
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/font-awesome/4.0.0/css/font-awesome.css" />
<script src="{{ asset('js/vendor/modernizr-2.6.2.min.js') }}"></script>
{% endblock %}
<link rel="icon" type="image/x-icon" href="{{ asset('favicon.ico') }}" />
</head>
<body>
{% block body %}{% endblock %}
{% block javascripts %}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js"></script>
<script src="https://code.angularjs.org/1.2.16/angular-route.min.js"></script>
<script src="{{ asset('js/main.js') }}"></script>
{% endblock %}
</body>
</html>
Templating
Problem:
{{ interpolation tags }} - used both by twig and AngularJS
Templating
{% verbatim %}
{{ message }}
{% endverbatim %}
Templating
var phpDayDemoApp = angular.module('phpDayDemoApp', [],
function($interpolateProvider) {
$interpolateProvider.startSymbol('[[');
$interpolateProvider.endSymbol(']]');
});
Now we can use
{% block content %}
[[ message ]] {# rendered by AngularJS #}
{% end block %}
Templating
Using assetic for minimize
{% javascripts
"js/angular-modules/mod1.js"
"#s/angular-modules/mod2.js"
"@AngBundle/Resources/public/js/controller/*.js"
output="compiled/js/app.js"
%}
<script type="text/javascript" src="{{ asset_url }}"></script>
{% endjavascripts %}
Templating
Using assetic for minimize
Since Angular infers the controller's dependencies from the names of
arguments to the controller's constructor function, if you were to minify the
JavaScript code for PhoneListCtrl controller, all of its function arguments
would be minified as well, and the dependency injector would not be able
to identify services correctly.
Use an inline annotation where, instead of just providing the function, you
provide an array. This array contains a list of the service names, followed by
the function itself.
function PhoneListCtrl($scope, $http) {...}
phonecatApp.controller('phpDayCtrl', ['$scope', '$http', PhoneListCtrl]);
Managing routes
Client side:
ngRoute
independent since Angular 1.1.6
hashbang #! & HTML5 mode
<base href="/">
$locationProvider
.html5Mode(true)
.hashPrefix('!');
Managing routes
http://localhost/todos
http://localhost/#todos
Resolving conflicts
Fallback, managing 404
Managing routes
Client side:
// module configuration...$routeProvider.when('/todos/show/:id', {
templateUrl : 'todo/show',
controller : 'todoController'
})
// receive paramssfugDemoApp.controller('todoController', function($scope, $http, $routeParams){
$scope.todo = {};
$http
.get('/api/todo/show/' + $routeParams.id)
.success(function(data){
$scope.todo = data['todo'];
});
});
Managing routes
Server side:
locastic_rest_todo_getall:
pattern: /api/get-all
defaults:
_controller: LocasticRestBundle:Todo:getAll
locastic_rest_todo_create:
pattern: /api/create
defaults:
_controller: LocasticRestBundle:Todo:create
locastic_rest_todo_show:
pattern: /api/show/{id}
defaults:
_controller: LocasticRestBundle:Todo:show
Translations
AngularJS has its own translation system
I18N/L10N . But it might be interesting to monitor
and centralize translations from your backend
Symfony.
Forms
Symfony Forms <3
We don't want to throw them away
Build custom directive
Forms
sfugDemoApp.directive('ngToDoForm', function() {
return {
restrict: 'E',
template: '<div class="todoForm">Form will be!</div>'
}
});
'A' - <span ng-sparkline></span>
'E' - <ng-sparkline></ng-sparkline>
'C' - <span class="ng-sparkline"></span>
'M' - <!-- directive: ng-sparkline →
Usage of directive in HTML:
<ng-to-do-form></ng-to-do-form>
Forms
sfugDemoApp.directive('ngToDoForm', function() {
return {
restrict: 'E',
templateUrl: '/api/form/show.html'
}
});
Forms
sfugDemoApp.directive('ngToDoForm', function() {
return {
restrict: 'E',
templateUrl: '/api/form/show.html'
}
});
locastic_show_form:
pattern: /form/show.html
defaults:
_controller: LocasticWebBundle:Default:renderForm
public function renderFormAction()
{
$form = $this->createForm(new TodoType());
return $this->render('LocasticWebBundle::render_form.html.twig', array(
'form' => $form->createView()
));
}
Forms
Suprise!!!
Form
Template behind directive
<form class="form-inline" role="form" style="margin-bottom: 30px;">
Create new todo:
<div class="form-group">
{{ form_label(form.description) }}
{{ form_widget(form.description, {'attr': {'ng-model': 'newTodo.description', 'placeholder':
'description', 'class': 'form-control'}}) }}
</div>
<div class="form-group">
<label class="sr-only" for="deadline">Deadline</label>
<input type="text" class="form-control" id="deadline" placeholder="deadline (angular-ui)" ng-
model="newTodo.deadline">
</div>
<input type="button" class="btn btn-default" ng-click="addNew()" value="add"/>
</form>
Testing
Symfony and AngularJS are designed to test. So write test
Behat
PHPUnit
PHPSpec
Jasmine
…
Or whatever you want just write tests
Summary
The cleanest way is to separate backend and frontend. But there is some
advantages to use both together.
Twig + HTML works well.
Assetic Bundle is very useful to minify bunches of Javascript files used by
AngularJs
Translation in the template. the data in the API payload does not need
translation in most cases. Using Symfony I18N support for the template
makes perfect sense.
Loading of Option lists. Say you have a country list with 200+ options. You
can build an API to populate a dynamic dropdown in angularjs, but as these
And remember
Keep controllers small and stupid, master Dependency
injection, delegate to services and events.
Thank you!
QA
Please rate my talk
https://joind.in/talk/view/11290
follow me on twitter: @antonioperic

More Related Content

What's hot (20)

PDF
Mojolicious, real-time web framework
taggg
 
PDF
Using Renderless Components in Vue.js during your software development.
tothepointIT
 
PDF
Symfony Guard Authentication: Fun with API Token, Social Login, JWT and more
Ryan Weaver
 
ZIP
Mojolicious
Marcus Ramberg
 
PDF
Microservice Teststrategie mit Symfony2
Per Bernhardt
 
PDF
#31.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...
탑크리에듀(구로디지털단지역3번출구 2분거리)
 
PDF
New Symfony Tips & Tricks (SymfonyCon Paris 2015)
Javier Eguiluz
 
PPT
Creating the interfaces of the future with the APIs of today
gerbille
 
PDF
Application Layer in PHP
Per Bernhardt
 
PDF
A Little Backbone For Your App
Luca Mearelli
 
PDF
Laravel 로 배우는 서버사이드 #5
성일 한
 
PDF
Curso Symfony - Clase 4
Javier Eguiluz
 
PDF
Introducing Assetic: Asset Management for PHP 5.3
Kris Wallsmith
 
PDF
Symfony & Javascript. Combining the best of two worlds
Ignacio Martín
 
PDF
OSCON Google App Engine Codelab - July 2010
ikailan
 
PDF
And now you have two problems. Ruby regular expressions for fun and profit by...
Codemotion
 
PDF
Sane Async Patterns
TrevorBurnham
 
PDF
Symfony 2
Kris Wallsmith
 
PDF
Controlling The Cloud With Python
Luca Mearelli
 
Mojolicious, real-time web framework
taggg
 
Using Renderless Components in Vue.js during your software development.
tothepointIT
 
Symfony Guard Authentication: Fun with API Token, Social Login, JWT and more
Ryan Weaver
 
Mojolicious
Marcus Ramberg
 
Microservice Teststrategie mit Symfony2
Per Bernhardt
 
#31.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...
탑크리에듀(구로디지털단지역3번출구 2분거리)
 
New Symfony Tips & Tricks (SymfonyCon Paris 2015)
Javier Eguiluz
 
Creating the interfaces of the future with the APIs of today
gerbille
 
Application Layer in PHP
Per Bernhardt
 
A Little Backbone For Your App
Luca Mearelli
 
Laravel 로 배우는 서버사이드 #5
성일 한
 
Curso Symfony - Clase 4
Javier Eguiluz
 
Introducing Assetic: Asset Management for PHP 5.3
Kris Wallsmith
 
Symfony & Javascript. Combining the best of two worlds
Ignacio Martín
 
OSCON Google App Engine Codelab - July 2010
ikailan
 
And now you have two problems. Ruby regular expressions for fun and profit by...
Codemotion
 
Sane Async Patterns
TrevorBurnham
 
Symfony 2
Kris Wallsmith
 
Controlling The Cloud With Python
Luca Mearelli
 

Viewers also liked (20)

PDF
Symfony + AngularJS | Mladen Plavsic @DaFED26
Mladen Plavšić
 
PDF
Symfony and Angularjs
Iwan van Staveren
 
ODP
Desarrollo Web Ágil con Symfony, Bootstrap y Angular
Freelancer
 
PPTX
Symfony with angular.pptx
Esokia
 
PDF
deSymfony 2013 - Creando aplicaciones web desde otro ángulo con Symfony y A...
Pablo Godel
 
PDF
A Practical Introduction to Symfony2
Kris Wallsmith
 
PPT
Symfony 2 : chapitre 4 - Les services et les formulaires
Abdelkader Rhouati
 
PDF
REST APIs in the context of single-page applications
yoranbe
 
PDF
برنامج جمعية بسمة أمل بوجدة لسنة 2013
Abdelkader Rhouati
 
PDF
Symfony2 e Elasticsearch com FosElasticaBundle
Waldemar Neto
 
PDF
Maintainable + Extensible = Clean ... yes, Code!
Antonio Peric-Mazar
 
PDF
Starting with Symfony2
Kevin Bond
 
PDF
Bash Scripting
Marian Marinov
 
PDF
Applications secure by default
SecuRing
 
PPTX
PPT on Angular 2 Development Tutorial
Paddy Lock
 
PDF
Bash Scripting
Vincent Claes
 
PDF
LVIV IT Arena - SmartHome using low cost components
Oriol Rius
 
PDF
Javascript Memory leaks and Performance & Angular
Erik Guzman
 
PPTX
Java9 moduulit jigsaw
Arto Santala
 
PDF
AngularJS - Overcoming performance issues. Limits.
Dragos Mihai Rusu
 
Symfony + AngularJS | Mladen Plavsic @DaFED26
Mladen Plavšić
 
Symfony and Angularjs
Iwan van Staveren
 
Desarrollo Web Ágil con Symfony, Bootstrap y Angular
Freelancer
 
Symfony with angular.pptx
Esokia
 
deSymfony 2013 - Creando aplicaciones web desde otro ángulo con Symfony y A...
Pablo Godel
 
A Practical Introduction to Symfony2
Kris Wallsmith
 
Symfony 2 : chapitre 4 - Les services et les formulaires
Abdelkader Rhouati
 
REST APIs in the context of single-page applications
yoranbe
 
برنامج جمعية بسمة أمل بوجدة لسنة 2013
Abdelkader Rhouati
 
Symfony2 e Elasticsearch com FosElasticaBundle
Waldemar Neto
 
Maintainable + Extensible = Clean ... yes, Code!
Antonio Peric-Mazar
 
Starting with Symfony2
Kevin Bond
 
Bash Scripting
Marian Marinov
 
Applications secure by default
SecuRing
 
PPT on Angular 2 Development Tutorial
Paddy Lock
 
Bash Scripting
Vincent Claes
 
LVIV IT Arena - SmartHome using low cost components
Oriol Rius
 
Javascript Memory leaks and Performance & Angular
Erik Guzman
 
Java9 moduulit jigsaw
Arto Santala
 
AngularJS - Overcoming performance issues. Limits.
Dragos Mihai Rusu
 
Ad

Similar to Symfony2 and AngularJS (20)

PDF
WebNet Conference 2012 - Designing complex applications using html5 and knock...
Fabio Franzini
 
PDF
Code igniter - A brief introduction
Commit University
 
PDF
Webservices in SalesForce (part 1)
Mindfire Solutions
 
ODP
Knolx session
Knoldus Inc.
 
PDF
Intro to Laravel 4
Singapore PHP User Group
 
PDF
Next Generation Spring MVC with Spring Roo
Stefan Schmidt
 
PDF
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)
Igor Bronovskyy
 
PDF
Angular server side rendering - Strategies & Technics
Eliran Eliassy
 
PPTX
Creating your own framework on top of Symfony2 Components
Deepak Chandani
 
PPTX
AngularJS training - Day 1 - Basics: Why, What and basic features of AngularJS
murtazahaveliwala
 
ODP
Exploring Symfony's Code
Wildan Maulana
 
PPTX
SharePoint Fest Seattle - SharePoint Framework, Angular & Azure Functions
Sébastien Levert
 
PDF
Building Isomorphic Apps (JSConf.Asia 2014)
Spike Brehm
 
PPTX
Let's play with adf 3.0
Eugenio Romano
 
PPT
Build Your Own CMS with Apache Sling
Bob Paulin
 
PDF
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
scalaconfjp
 
PDF
Xitrum @ Scala Matsuri Tokyo 2014
Ngoc Dao
 
PDF
Creating a modern web application using Symfony API Platform, ReactJS and Red...
Jesus Manuel Olivas
 
PPTX
Writing HTML5 Web Apps using Backbone.js and GAE
Ron Reiter
 
PPS
Simplify your professional web development with symfony
Francois Zaninotto
 
WebNet Conference 2012 - Designing complex applications using html5 and knock...
Fabio Franzini
 
Code igniter - A brief introduction
Commit University
 
Webservices in SalesForce (part 1)
Mindfire Solutions
 
Knolx session
Knoldus Inc.
 
Intro to Laravel 4
Singapore PHP User Group
 
Next Generation Spring MVC with Spring Roo
Stefan Schmidt
 
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)
Igor Bronovskyy
 
Angular server side rendering - Strategies & Technics
Eliran Eliassy
 
Creating your own framework on top of Symfony2 Components
Deepak Chandani
 
AngularJS training - Day 1 - Basics: Why, What and basic features of AngularJS
murtazahaveliwala
 
Exploring Symfony's Code
Wildan Maulana
 
SharePoint Fest Seattle - SharePoint Framework, Angular & Azure Functions
Sébastien Levert
 
Building Isomorphic Apps (JSConf.Asia 2014)
Spike Brehm
 
Let's play with adf 3.0
Eugenio Romano
 
Build Your Own CMS with Apache Sling
Bob Paulin
 
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
scalaconfjp
 
Xitrum @ Scala Matsuri Tokyo 2014
Ngoc Dao
 
Creating a modern web application using Symfony API Platform, ReactJS and Red...
Jesus Manuel Olivas
 
Writing HTML5 Web Apps using Backbone.js and GAE
Ron Reiter
 
Simplify your professional web development with symfony
Francois Zaninotto
 
Ad

More from Antonio Peric-Mazar (20)

PDF
You call yourself a Senior Developer?
Antonio Peric-Mazar
 
PDF
Using API Platform to build ticketing system #symfonycon
Antonio Peric-Mazar
 
PDF
Using API platform to build ticketing system (translations, time zones, ...) ...
Antonio Peric-Mazar
 
PDF
Are you failing at being agile? #digitallabin
Antonio Peric-Mazar
 
PDF
Symfony 4: A new way to develop applications #ipc19
Antonio Peric-Mazar
 
PDF
A year with progressive web apps! #webinale
Antonio Peric-Mazar
 
PDF
The UI is the THE application #dpc19
Antonio Peric-Mazar
 
PDF
Symfony 4: A new way to develop applications #phpsrb
Antonio Peric-Mazar
 
PDF
REST easy with API Platform
Antonio Peric-Mazar
 
PDF
A year with progressive web apps! #DevConMU
Antonio Peric-Mazar
 
PDF
Service workers are your best friends
Antonio Peric-Mazar
 
PDF
Progressive Web Apps are here!
Antonio Peric-Mazar
 
PDF
Building APIs in an easy way using API Platform
Antonio Peric-Mazar
 
PDF
Symfony4 - A new way of developing web applications
Antonio Peric-Mazar
 
PDF
Build your business on top of Open Source
Antonio Peric-Mazar
 
PDF
Building APIs in an easy way using API Platform
Antonio Peric-Mazar
 
PDF
Lessons learned while developing with Sylius
Antonio Peric-Mazar
 
PDF
Drupal8 for Symfony developers - Dutch PHP
Antonio Peric-Mazar
 
PDF
Drupal8 for Symfony Developers (PHP Day Verona 2017)
Antonio Peric-Mazar
 
PDF
Drupal8 for Symfony Developers
Antonio Peric-Mazar
 
You call yourself a Senior Developer?
Antonio Peric-Mazar
 
Using API Platform to build ticketing system #symfonycon
Antonio Peric-Mazar
 
Using API platform to build ticketing system (translations, time zones, ...) ...
Antonio Peric-Mazar
 
Are you failing at being agile? #digitallabin
Antonio Peric-Mazar
 
Symfony 4: A new way to develop applications #ipc19
Antonio Peric-Mazar
 
A year with progressive web apps! #webinale
Antonio Peric-Mazar
 
The UI is the THE application #dpc19
Antonio Peric-Mazar
 
Symfony 4: A new way to develop applications #phpsrb
Antonio Peric-Mazar
 
REST easy with API Platform
Antonio Peric-Mazar
 
A year with progressive web apps! #DevConMU
Antonio Peric-Mazar
 
Service workers are your best friends
Antonio Peric-Mazar
 
Progressive Web Apps are here!
Antonio Peric-Mazar
 
Building APIs in an easy way using API Platform
Antonio Peric-Mazar
 
Symfony4 - A new way of developing web applications
Antonio Peric-Mazar
 
Build your business on top of Open Source
Antonio Peric-Mazar
 
Building APIs in an easy way using API Platform
Antonio Peric-Mazar
 
Lessons learned while developing with Sylius
Antonio Peric-Mazar
 
Drupal8 for Symfony developers - Dutch PHP
Antonio Peric-Mazar
 
Drupal8 for Symfony Developers (PHP Day Verona 2017)
Antonio Peric-Mazar
 
Drupal8 for Symfony Developers
Antonio Peric-Mazar
 

Recently uploaded (20)

PDF
Download Canva Pro 2025 PC Crack Full Latest Version
bashirkhan333g
 
PDF
The 5 Reasons for IT Maintenance - Arna Softech
Arna Softech
 
PPTX
ChiSquare Procedure in IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
PDF
MiniTool Power Data Recovery 8.8 With Crack New Latest 2025
bashirkhan333g
 
PPTX
Empowering Asian Contributions: The Rise of Regional User Groups in Open Sour...
Shane Coughlan
 
PDF
Top Agile Project Management Tools for Teams in 2025
Orangescrum
 
PDF
Simplify React app login with asgardeo-sdk
vaibhav289687
 
PDF
IDM Crack with Internet Download Manager 6.42 Build 43 with Patch Latest 2025
bashirkhan333g
 
PDF
SAP Firmaya İade ABAB Kodları - ABAB ile yazılmıl hazır kod örneği
Salih Küçük
 
PDF
IObit Driver Booster Pro 12.4.0.585 Crack Free Download
henryc1122g
 
PPTX
Home Care Tools: Benefits, features and more
Third Rock Techkno
 
PDF
Technical-Careers-Roadmap-in-Software-Market.pdf
Hussein Ali
 
PDF
SciPy 2025 - Packaging a Scientific Python Project
Henry Schreiner
 
PPTX
Agentic Automation: Build & Deploy Your First UiPath Agent
klpathrudu
 
PDF
NSF Converter Simplified: From Complexity to Clarity
Johnsena Crook
 
PDF
Dipole Tech Innovations – Global IT Solutions for Business Growth
dipoletechi3
 
PPTX
Change Common Properties in IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
PPTX
Get Started with Maestro: Agent, Robot, and Human in Action – Session 5 of 5
klpathrudu
 
PPTX
OpenChain @ OSS NA - In From the Cold: Open Source as Part of Mainstream Soft...
Shane Coughlan
 
PPTX
Finding Your License Details in IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
Download Canva Pro 2025 PC Crack Full Latest Version
bashirkhan333g
 
The 5 Reasons for IT Maintenance - Arna Softech
Arna Softech
 
ChiSquare Procedure in IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
MiniTool Power Data Recovery 8.8 With Crack New Latest 2025
bashirkhan333g
 
Empowering Asian Contributions: The Rise of Regional User Groups in Open Sour...
Shane Coughlan
 
Top Agile Project Management Tools for Teams in 2025
Orangescrum
 
Simplify React app login with asgardeo-sdk
vaibhav289687
 
IDM Crack with Internet Download Manager 6.42 Build 43 with Patch Latest 2025
bashirkhan333g
 
SAP Firmaya İade ABAB Kodları - ABAB ile yazılmıl hazır kod örneği
Salih Küçük
 
IObit Driver Booster Pro 12.4.0.585 Crack Free Download
henryc1122g
 
Home Care Tools: Benefits, features and more
Third Rock Techkno
 
Technical-Careers-Roadmap-in-Software-Market.pdf
Hussein Ali
 
SciPy 2025 - Packaging a Scientific Python Project
Henry Schreiner
 
Agentic Automation: Build & Deploy Your First UiPath Agent
klpathrudu
 
NSF Converter Simplified: From Complexity to Clarity
Johnsena Crook
 
Dipole Tech Innovations – Global IT Solutions for Business Growth
dipoletechi3
 
Change Common Properties in IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
Get Started with Maestro: Agent, Robot, and Human in Action – Session 5 of 5
klpathrudu
 
OpenChain @ OSS NA - In From the Cold: Open Source as Part of Mainstream Soft...
Shane Coughlan
 
Finding Your License Details in IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 

Symfony2 and AngularJS

  • 1. Symfony2 and AngularJS Antonio Perić-Mažar 16.05.2014, PHPday Verona https://joind.in/talk/view/11290
  • 2. About me • Antonio Perić-Mažar, mag. ing. comp. • CEO @ locastic • Software developer, Symfony2 • Sylius Awesome Contributor :) • www.locastic.com • [email protected] • twitter: @antonioperic
  • 3. Who we are? • locastic (www.locastic.com) • Web and mobile development • UI/UX design • Located in Split, Croatia
  • 6. Symfony2  PHP Framework, server side  MVC, HTTP  Toolbox, methodology  One of the most advanced PHP framework  Strong community  Easy to test it
  • 7. Symfony2  Bundles  Components  Routing  Templating (Twig)  Forms  etc
  • 8. AngularJS  Client-side JavaScript framework  Prescriptive, MVC (MVVM)  Makes creating UI easier thought data-binding  Good organizing and architecture  Learning curve, easy to start hard to master  $scope, modules, controllers, providers, services
  • 9. AngularJS Core Two-way data binding JS: <span id=”someId”></span> document.getElementById('someId').text = 'locastic'; NG <span>{{someName}}<span> var someName = 'locastic';
  • 10. AngularJS Core <html ng-app> <head> <script src=”angular.js”></script> <script src=”controller.js”></script> <head> <body> <div ng-controller=”HelloController”> <p>{{ greeting.text}}, World</p> </div> </body> </html> // controller.js function HelloController($scope) { $scope.gretting = {text: 'Hello'} } HTML template
  • 11. AngularJS Core  Deep Linking  Dependency Injection  Directives <div class=”container”> <div class=”inner> <ul> <li>Item <div class=”subitem”>Item2</div> </li> </ul> </div> </div> <dropdown> <item>Item 1> <subitem >Item 2</subitem> </item> </dropdown>
  • 13. SPA  Aka SPI (Single Page interface)  desktop apps UX  HTML / JS / CSS / etc in single page load  fast  AJAX and XHR
  • 15. SPA Arhitecture Backend (rest api) with Symfony2 Frontend with AngularJs Separation or combination?
  • 17. Symfony2 AngularJS Usage, language Backend, PHP Frontend, Javascript Dependency Injection Yes Yes Templating Twig HTML Form component Yes Yes Routing component Yes Yes MVC Yes Yes Testable Yes Yes Services Yes Yes Events Yes Yes i18n Yes Yes Dependency management Yes Yes
  • 18. RESTful ws Simpler than SOAP & WSDL Resource-oriented (URI) Principles: HTTP methods (idempotent & not) stateless directory structure-like URIs XML or JSON (or XHTML)
  • 19. Building Rest Api with SF2 There is bundle for everything in Sf2. Right? So lets use some of them!
  • 20. Building Rest Api with SF2 What we need? JMSSerializerBundle FOSRestBundle NelmioApiDocBundle
  • 21. Building Rest API with SF2 JMSSerializerBundle (de)serialization via annotations / YAML / XML / PHP integration with the Doctrine ORM handling of other complex cases (e.g. circular references)
  • 22. Building Rest Api with SF2 LocasticBundleTodoBundleEntityTodo: # exclusion_policy: ALL exclusion_policy: NONE properties: # description: # expose: true createdAt: # expose: true exclude: true deadline: type: DateTime<'d.m.Y. H:i:s'> # expose: true done: # expose: true serialized_name: status
  • 23. Building Rest Api with SF2 fos_rest: disable_csrf_role: ROLE_API param_fetcher_listener: true view: view_response_listener: 'force' formats: xml: true json: true templating_formats: html: true format_listener: rules: - { path: ^/, priorities: [ html, json, xml ], fallback_format: ~, prefer_extension: true } exception: codes: 'SymfonyComponentRoutingExceptionResourceNotFoundException': 404 'DoctrineORMOptimisticLockException': HTTP_CONFLICT messages: 'SymfonyComponentRoutingExceptionResourceNotFoundException': true allowed_methods_listener: true access_denied_listener: json: true body_listener: true
  • 24. Building Rest Api with SF2 /** * @ApiDoc( * resource = true, * description = "Get stories from users that you follow (newsfeed)", * section = "Feed", * output={ * "class" = "LocasticBundleFeedBundleEntityStory" * }, * statusCodes = { * 200 = "Returned when successful", * 400 = "Returned when bad parameters given" * } * ) * * @RestView( * serializerGroups = {"feed"} * ) */ public function getFeedAction() { $this->get('locastic_auth.auth.handler')->validateRequest($this->get('request')); return $this->getDoctrine()->getRepository('locastic.repository.story')->getStories($this->get('request')- >get('me')); }
  • 25. Building Rest Api with SF2
  • 27. Templating <!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>{% block title %}Welcome!{% endblock %}</title> {% block stylesheets %} <!-- Place favicon.ico and apple-touch-icon.png in the root directory --> {#<link rel="stylesheet" href="{{ asset('css/normalize.css') }}">#} <link rel="stylesheet" href="{{ asset('css/main.css') }}"> <!-- load bootstrap and fontawesome via CDN --> <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" /> <link rel="stylesheet" href="//netdna.bootstrapcdn.com/font-awesome/4.0.0/css/font-awesome.css" /> <script src="{{ asset('js/vendor/modernizr-2.6.2.min.js') }}"></script> {% endblock %} <link rel="icon" type="image/x-icon" href="{{ asset('favicon.ico') }}" /> </head> <body> {% block body %}{% endblock %} {% block javascripts %} <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js"></script> <script src="https://code.angularjs.org/1.2.16/angular-route.min.js"></script> <script src="{{ asset('js/main.js') }}"></script> {% endblock %} </body> </html>
  • 28. Templating Problem: {{ interpolation tags }} - used both by twig and AngularJS
  • 29. Templating {% verbatim %} {{ message }} {% endverbatim %}
  • 30. Templating var phpDayDemoApp = angular.module('phpDayDemoApp', [], function($interpolateProvider) { $interpolateProvider.startSymbol('[['); $interpolateProvider.endSymbol(']]'); }); Now we can use {% block content %} [[ message ]] {# rendered by AngularJS #} {% end block %}
  • 31. Templating Using assetic for minimize {% javascripts "js/angular-modules/mod1.js" "#s/angular-modules/mod2.js" "@AngBundle/Resources/public/js/controller/*.js" output="compiled/js/app.js" %} <script type="text/javascript" src="{{ asset_url }}"></script> {% endjavascripts %}
  • 32. Templating Using assetic for minimize Since Angular infers the controller's dependencies from the names of arguments to the controller's constructor function, if you were to minify the JavaScript code for PhoneListCtrl controller, all of its function arguments would be minified as well, and the dependency injector would not be able to identify services correctly. Use an inline annotation where, instead of just providing the function, you provide an array. This array contains a list of the service names, followed by the function itself. function PhoneListCtrl($scope, $http) {...} phonecatApp.controller('phpDayCtrl', ['$scope', '$http', PhoneListCtrl]);
  • 33. Managing routes Client side: ngRoute independent since Angular 1.1.6 hashbang #! & HTML5 mode <base href="/"> $locationProvider .html5Mode(true) .hashPrefix('!');
  • 35. Managing routes Client side: // module configuration...$routeProvider.when('/todos/show/:id', { templateUrl : 'todo/show', controller : 'todoController' }) // receive paramssfugDemoApp.controller('todoController', function($scope, $http, $routeParams){ $scope.todo = {}; $http .get('/api/todo/show/' + $routeParams.id) .success(function(data){ $scope.todo = data['todo']; }); });
  • 36. Managing routes Server side: locastic_rest_todo_getall: pattern: /api/get-all defaults: _controller: LocasticRestBundle:Todo:getAll locastic_rest_todo_create: pattern: /api/create defaults: _controller: LocasticRestBundle:Todo:create locastic_rest_todo_show: pattern: /api/show/{id} defaults: _controller: LocasticRestBundle:Todo:show
  • 37. Translations AngularJS has its own translation system I18N/L10N . But it might be interesting to monitor and centralize translations from your backend Symfony.
  • 38. Forms Symfony Forms <3 We don't want to throw them away Build custom directive
  • 39. Forms sfugDemoApp.directive('ngToDoForm', function() { return { restrict: 'E', template: '<div class="todoForm">Form will be!</div>' } }); 'A' - <span ng-sparkline></span> 'E' - <ng-sparkline></ng-sparkline> 'C' - <span class="ng-sparkline"></span> 'M' - <!-- directive: ng-sparkline → Usage of directive in HTML: <ng-to-do-form></ng-to-do-form>
  • 40. Forms sfugDemoApp.directive('ngToDoForm', function() { return { restrict: 'E', templateUrl: '/api/form/show.html' } });
  • 41. Forms sfugDemoApp.directive('ngToDoForm', function() { return { restrict: 'E', templateUrl: '/api/form/show.html' } }); locastic_show_form: pattern: /form/show.html defaults: _controller: LocasticWebBundle:Default:renderForm public function renderFormAction() { $form = $this->createForm(new TodoType()); return $this->render('LocasticWebBundle::render_form.html.twig', array( 'form' => $form->createView() )); }
  • 43. Form Template behind directive <form class="form-inline" role="form" style="margin-bottom: 30px;"> Create new todo: <div class="form-group"> {{ form_label(form.description) }} {{ form_widget(form.description, {'attr': {'ng-model': 'newTodo.description', 'placeholder': 'description', 'class': 'form-control'}}) }} </div> <div class="form-group"> <label class="sr-only" for="deadline">Deadline</label> <input type="text" class="form-control" id="deadline" placeholder="deadline (angular-ui)" ng- model="newTodo.deadline"> </div> <input type="button" class="btn btn-default" ng-click="addNew()" value="add"/> </form>
  • 44. Testing Symfony and AngularJS are designed to test. So write test Behat PHPUnit PHPSpec Jasmine … Or whatever you want just write tests
  • 45. Summary The cleanest way is to separate backend and frontend. But there is some advantages to use both together. Twig + HTML works well. Assetic Bundle is very useful to minify bunches of Javascript files used by AngularJs Translation in the template. the data in the API payload does not need translation in most cases. Using Symfony I18N support for the template makes perfect sense. Loading of Option lists. Say you have a country list with 200+ options. You can build an API to populate a dynamic dropdown in angularjs, but as these
  • 46. And remember Keep controllers small and stupid, master Dependency injection, delegate to services and events.
  • 48. QA Please rate my talk https://joind.in/talk/view/11290 follow me on twitter: @antonioperic