Angular Pusher Factory to Centralize Code (also using Laravel to set constants and properties)

Posted: 2014-10-24 01:27:36

This will cover

  • Making an Angular factory to centralize Pusher setup in Angular
  • Passing settings form Laravel to Angular (though could be just Angular and a .env file as well)
  • Passing Constants into the Angular App to pass these settings around, in this case to the Pusher Factory.

Setup your constants

This is where I call in the info I need to use later on.

(function(){

  function config($stateProvider, $urlRouterProvider) {
      $urlRouterProvider.otherwise("/dashboard");
      $stateProvider
          .state('dashboard', {
              url: "/dashboard",
              views: {
                '': {
                    controller: 'DashCtrl',
                    controllerAs: 'vm',
                    resolve: {
                        reports: ['ReportsService', function(ReportsService)
                        {
                            return ReportsService.get();
                        }]
                    },
                    templateUrl: "/assets/js/dashboard/templates/dashboard.html"
                };
  }

  function constants() {
     return { 'pusher_public_key': window.pusher_public_key }
  }

angular
    .module('app')
    .config(config)
    .constant('ENV', constants())
    .run(function($rootScope, $state) {
        $rootScope.$state = $state;
    });
})();

So now we have the constants in place that are used by our factory below

The Pusher Factory

(function(){
    'use strict';
    function PusherService(ENV)
    {
        var vm = this;
        vm.pusher = {};
        vm.ENV = ENV; //We set this up above on the constants area.
        vm.channelSet = {};
        vm.activate = activate;
        vm._subscribeToChannel = _subscribeToChannel;
        vm._channelBind = _channelBind;

        vm.PusherService = {
            setPusher: setPusher
        };

        vm.activate();

        ////
        function activate()
        {
            console.log(vm.ENV);
            vm.pusher = new Pusher(vm.ENV.pusher_public_key);
        }

        function setPusher(channel, event, callback)
        {
            vm._subscribeToChannel(channel);
            vm._channelBind(event, callback);
        }

        function _subscribeToChannel(channel)
        {
            vm.channelSet = vm.pusher.subscribe(channel);
        }

        function _channelBind(event_name, callback)
        {
            vm.channelSet.bind(event_name, callback);
        }

        return vm.PusherService;
    }

    angular.module('app')
        .factory('PusherService', PusherService);
})();

Laravel now need to load the settings in the .env file so Angular can access them later.

Of course this could purely be Angular.js loading them from a config file that is not in git but relative to a server, local dev area etc.

I set this all up user https://github.com/laracasts/PHP-Vars-To-Js-Transformer

I run the config command note the change

php artisan publish:config laracasts/utilities

Then I edit that file

config/packages/laracasts/utilities/config.php

To be

<?php

return [

    /*
    |--------------------------------------------------------------------------
    | View to Bind JavaScript Vars To
    |--------------------------------------------------------------------------
    |
    | Set this value to the name of the view (or partial) that
    | you want to prepend the JavaScript variables to.
    |
    */
    'bind_js_vars_to_this_view' => 'layouts/main',

    /*
    |--------------------------------------------------------------------------
    | JavaScript Namespace
    |--------------------------------------------------------------------------
    |
    | By default, we'll add variables to the global window object.
    | It's recommended that you change this to some namespace - anything.
    | That way, from your JS, you may do something like `Laracasts.myVar`.
    |
    */
    'js_namespace' => 'window'

];

The resources/views/layouts/main.blade.php the only trick here is any Angular related {{ brackets need to be @{{ to tell blade to ignore them.

Finally my AngularController which renders the ONE page Laravel is in charge of besides login.

<?php namespace App\Http\Controllers;

use Laracasts\Utilities\JavaScript\Facades\JavaScript;

/**
 * @Middleware("auth")
 */
class AngularController extends BaseController {


    /**
     * @Get("dash", as="dash")
     */
    public function index()
    {
        JavaScript::put([
            'pusher_public_key' => $_ENV['PUSHER_PUBLIC']]);
        return view('layouts.main');
    }

}

If you have more than on View the share option might work http://laravel.com/docs/master/views