angularjssymfonywebpacksymfony4symfony-flex

Webpack FOSJsRoutingBundle integration with Symfony Flex and Angular


I cannot get FOSJsRoutingBundle to work with Symfony Flex, Webpack and AngularJS.

I've been using this bundle in Symfony 3 with AngularJS for a long time and there's never been an issue but with the introduction of webpack in Symfony Flex, the setup has become more complex. Unfortunately the documentation for FOSJsRoutingBundle version 2.2 isn't clear.

You can find the current documentation for this bundle here.

I am using the FOSJsRoutingBundle so that my Angular HTTP requests can use the generated routes rather than absolute URLs.

The Problem

I have setup this bundle as documented through composer. The routes are then dumped to a json file located at code/assets/fos_js_routes.json. The generated routes in this file are valid and what I expect to see.

As I am using Angular I want to do the initial required declaration of the Routing in a separate file so that all of my Angular controllers can use the Routing. without having to do any further work in those files.


FOS setup file /code/assets/js/fos_js_router.js (Following documentation)

const routes = require('../../assets/fos_js_routes.json');
import Routing from '../../vendor/friendsofsymfony/jsrouting-bundle/Resources/public/js/router.min.js';

Routing.setRoutingData(routes);

Sample Angular file /code/assets/js/apps/default/controller/test.js

(function () {

    'use strict';

    angular.module('test')
    .controller(
        'TestCtrl',
        ['$scope', '$http',
            function ($scope, $http) {

                let url = Routing.generate('test_route_name');
             }
         ])
});

Webpack Config

var Encore = require('@symfony/webpack-encore');

Encore
    .setOutputPath('public/build/')
    .setPublicPath('/build')
    .addEntry('app', './assets/js/app.js')
    .addEntry('app_fos_router', [
        './assets/js/fos_js_router.js'
    ])
    .addEntry('app_angular', [
        './assets/js/apps/default/app.js', // angular app setup
        './assets/js/apps/default/routes.js', // angular routes setup
        './assets/js/apps/default/controller/test.js' // angular where Routing is needed
    ])
    .enableSingleRuntimeChunk()
    .cleanupOutputBeforeBuild()
    .enableBuildNotifications()
    .enableSourceMaps(!Encore.isProduction())
    .enableVersioning(Encore.isProduction())
;

module.exports = Encore.getWebpackConfig();

Front-end twig template

{% extends 'base.html.twig' %}

{% block title %}Test{% endblock %}

{% block javascripts %}
    {{ encore_entry_script_tags('app') }}
    {{ encore_entry_script_tags('app_fos_router') }}
    {{ encore_entry_script_tags('app_angular') }}
{% endblock %}

{% block body %}
    <div ng-app="test" ui-view="content"></div>
{% endblock %}

The Error

From the above setup I get test.js: ReferenceError: Routing is not defined at in my AngularJS files.

What do I need to do differently so that I can make use of let url = Routing.generate('test_route_name'); in my AngularJS files?


Solution

  • Simple fix to get this working:

    const routes = require('../../assets/fos_js_routes.json');
    import Routing from '../../vendor/friendsofsymfony/jsrouting-bundle/Resources/public/js/router.min.js';
    
    Routing.setRoutingData(routes);
    window.Routing = Routing;