Laravel and Angular Widgets e.g. Non SPA (Single Page Application) Pattern

Posted: 2015-08-26 01:15:25

Not all apps need to be an SPA (Single Page Application). Sure they have their place but in most cases the task might benefit from just a Blade template and Angular widget. This saves you from having to write an angular route which can be a tedious duplication of work. Also Blade is fast and fun to work with.

Step One Add Data to Global Window

Using the Transform PHP Vars to JavaScript you can easily start to inject some content into your templates, if needed, to setup the data your Angular widget can use to build out it's elements.

For example the Controller below will push some info into the view that I can use later

<?php

namespace App\Http\Controllers;


use App\Campaign;
use App\Folder;
use App\Helpers\ReturnWebhook;
use App\Http\Requests;
use App\Providers\WebhookExtendedProvider;
use App\Utilities\GenerateSampleContent;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\Response;
use Michelf\MarkdownExtra;
use Rhumsaa\Uuid\Uuid;

class HelpController extends Controller
{
    use GenerateSampleContent;
    use ReturnWebhook;


    public function api()
    {
        $url = url();

        $apis['campaigns'] = 'api/v1/campaigns';

        $apis['campaigns_get'] = 'api/v1/campaigns/';

        $campaigns = Campaign::select('id', 'name')->groupBy('name')->orderBy('name')->get();

        $folders = Folder::with('meta_values')->groupBy('folders.id')->get();

        /**
         * Using the Javacript Library
         */
        \JavaScript::put([
            'campaigns' => $campaigns,
            'token' => csrf_token(),
            'folders' => $folders,
            'url' => $url,
            'apis' => $apis
        ]);

        $text = file_get_contents(base_path('docs/webhooks.md'));
        $webhooks = MarkdownExtra::defaultTransform($text);

        $api = file_get_contents(base_path('docs/api.md'));
        $api = MarkdownExtra::defaultTransform($api);

        return view('help.api', compact('webhooks', 'api', 'campaigns', 'url', 'apis', 'folders'));
    }


Setting Up the View and Angular

Now in the view for the Controller above we use that info. Note the Angular brackets @{{

See template here

So now that view is rendering both Blade data {{ and Angular.

You will see too I setup the Angular controller vm.addMarketoFolderNameToQuery keep in mind I already setup that ng-app in my main template file layouts.default

See Default Layout Here

Angular Controller

Here is the ApiController injected above. Notice we use Angular's $window to get the data we passed in from the Laravel Controller. You can also see it making API requests later on as the user clicks buttons etc.

(function(){
    'use strict';

    function ApiControllerUserShow($http, $window, toaster)
    {
        var vm = this;
        vm.getting_token = '';
        vm.user = $window.user;
        vm.url = $window.url;
        vm.message = "You do not have an API Key yet. Click the button below to make one";

        vm.getNewApi = getNewApi;

        activate();

        ///
        function activate()
        {
            console.log($window.user);

            setApiToken();
        }

        function getNewApi()
        {
            vm.getting_token = 'fa-spin';
            toaster.pop('info', "Getting new token");

            $http.get('/api/v1/create_client_token')
                .success(function(response) {
                    toaster.pop('info', "Loading new token");
                    console.log(response);
                    vm.getting_token = ''
                    vm.api_token = response.data;
                })
                .error(function(response) {
                    toaster.pop('error', "Could not get token please contact support");
                    console.log(response);
                });
        }

        function setApiToken()
        {
            //$user->oauth_client->oauth_session->oauth_access_tokens->id

            if(!vm.user.oauth_client)
            {
                vm.api_token = vm.message;
            }
            else if(!vm.user.oauth_client.oauth_session)
            {
                vm.api_token = vm.message;
            }
            else if(!vm.user.oauth_client.oauth_session.oauth_access_tokens)
            {
                vm.api_token = vm.message;
            }
            else
            {
                vm.api_token = vm.user.oauth_client.oauth_session.oauth_access_tokens.id;
            }

        }

    }

    angular.module('app')
        .controller('ApiControllerUserShow', ApiControllerUserShow);

})();

That is it. Keep in mind that Blade template can have numerous angular "widgets" so different sections of the page can benefit from Angular. Or the one page can have several places that the Angular controller controls some of the output.

So hopefully this sums up a quick way to start putting Angular widgets into your Laravel application and still benefit from all speed that these too tools offer both in developing and in rendering!