Drupal 8 + AngularJS Implementation

agungsuyono's picture

I'm trying to use AngularJS in Drupal 8 template. My objective is to get the power of drupal as a backend to do content query, and AngularJS as a front end to make a single one page application. I'm implementing AngularJS in drupal module with name drupal_ng. The complete code is in https://github.com/agungsuyono/drupal_ng. However, I'm wondering whether my implementation is not correct. Because I didn't see the result as expected; it seemed ng-controller didn't work in the HTML template. The javascript controller that I wrote did not bind to the HTML template.

Here are some of the code of drupal_ng module. I really appreciate for any support for this issue.

drupal_ng/drupal_ng.module

<?php
   
/**
     * Implements hook_theme().
     */
   
function drupal_ng_theme() {
      return array(
       
'drupal_ng_view' => array(
         
'template' => 'view',
         
'variables' => array('title' => NULL),
        ),
      );
    }
?>

drupal_ng/drupal_ng.libraries.yml

    angularjs:
      version: VERSION
      js:
        'https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.min.js':  {type: external}

    drupal_ng:
      js:
        js/drupal_ng.js: {}
      dependencies:
        - drupal_ng/angularjs

drupal_ng/src/Controller/DrupalNgController.php

<?php
   
namespace Drupal\drupal_ng\Controller;

    use
Drupal\Core\Controller\ControllerBase;

    class
DrupalNgController extends ControllerBase {

      public function
viewDrupalNg() {
       
$title = t('Hello!');
       
$build['myelement'] = array(
         
'#theme' => 'drupal_ng_view',
         
'#title' => $title,
        );
       
$build['myelement']['#attached']['library'][] = 'drupal_ng/angularjs';
       
$build['myelement']['#attached']['library'][] = 'drupal_ng/drupal_ng';
        return
$build;
      }
    }
?>

drupal_ng/js/drupal_ng.js

    var myApp = angular.module("myModule", []);

    myApp.controller("myController", function ($scope) {
      $scope.message = "This is AngularJS";
    });

The word "This is AngularJS" should appear in the HTML template below but it didn't.

drupal_ng/templates/view.html.twig

    <h2>{{  title }}</h2>

    <div ng-app="myModule">
      <div ng-controller="myController">
        {{ message }}
      </div>
    </div>

This is the screen shoot of the result in Chrome browser using AngularJS debugger. From the debugger, it seems that the message "This is AngularJS" is already there, but it didn't appear in the screen.

AttachmentSize
Screen Shot 2016-05-09 at 16.36.49.png444.8 KB

Comments

Multiple Projects Already Exist

tyler.frankenstein's picture

There are a few projects already trying to bridge the gap between Drupal and Angular, perhaps it is worth your time to check them out:

https://github.com/alexpsi/ng-drupal
https://github.com/easystreet3/angular-drupal
https://github.com/marthinal/ngDrupal

Thanks Tyler for your

agungsuyono's picture

Thanks Tyler for your recommendation. What I'm looking for is how the AngularJS can work in a Drupal 8 module template. I have taken a look of all those sites, however it seems they are not a Drupal module. Please correct me if I'm wrong.

Double curly braces

suryanto's picture

There is a conflict between angular double curly braces with twig. You need to wrap angular template section with verbatim twig tag.

    <h2>{{  title }}</h2>

    <div ng-app="myModule">
      <div ng-controller="myController">
        {% verbatim %}
          {{ message }}
        {% endverbatim %}
      </div>
    </div>

Reference: http://twig.sensiolabs.org/doc/tags/verbatim.html

Optionally you can also

cmcintosh's picture

Optionally you can also change the {{}} in angular to something else, like:

angular.module('myApp', []).config(function($interpolateProvider){
$interpolateProvider.startSymbol('<<').endSymbol('>>');
});

I did a blog post a while ago about a couple of ways Drupal / Angular can live together http://www.wembassy.com/blog/chris-mcintosh/drupal-8-different-methods-i....

But the basics is you can change the {{ }} of angular to really anything with the above config /$interpolateProvider.

Thanks Suryanto! Thanks

agungsuyono's picture

Thanks Suryanto! Thanks Chris! It works! Great! Thanks a lot!

Wow. great on SPA

sankarlpgym's picture

Hi,

Wow. This really made my day. Thanks a lot!

Can you help me in SEO part of SPA?

Thanks

Sankar

Angularjs Training in Chennai

I'm not sure how this works.

Hadi Farnoud's picture

I'm not sure how this works. you are using D8 as backend API only, right? then in theory you could use any js framework on frontend.

if that is true, the same can be done with Backbonejs?

Yes, by decoupling D8 from

bmateus's picture

Yes, by decoupling D8 from the front-end, any js can be used as the frontend.

Probably the simples way would be to just create JSON feeds by Views + Services. Then you can pickup the JSON feed independently by the js front-end. Even vanilla js can do it.

The following website uses Angular and D8 totally decoupled from it.

https://vilavitaparc.com

<< I tried others - still returned to Drupal. >>

SEO?

vorapoap's picture

Congratulation, and I just wonder, how do you deal with SEO problem?.. I see Google index some text of your web site.

Thank you for your knowledge

Actually, google already

bmateus's picture

Actually, google already indexes Javascript websites.

Problem arises with other engines like Baidu, Yandex, Bing, Facebook and others that don't support it yet.

For those cases we use a service like prerender.io. Basically, it caches a HTML rendered version of each page, and when our serves gets a request, it sends back the cached version in regular html.

It's a paid service, but there's an open-source you can install in your own server.

To change the meta-data of each page in Angular, I use Angular Update-Meta, https://github.com/jvandemo/angular-update-meta.

Hope it helps.

<< I tried others - still returned to Drupal. >>

Q: Would you recommend

wmike7's picture

Q: Would you recommend implementing Angular in a module (like this tutorial) or is there a preferred method?

-Mike

I think like many things it

cmcintosh's picture

I think like many things it depends on the situation. I would probably lean towards a module, but implement it as a Theme hook, so that things could be themed in the Theme layer as needed. I am doing something like that now for a search engine on a drupal 7 site.

Interesting, thank you for

wmike7's picture

Interesting, thank you for your insight.

-Mike

The only other suggestion I

cmcintosh's picture

The only other suggestion I would have is to utilize Require.js to handle loading the files, otherwise your preprocessor hooks and .info files can get large.

D8 + NG 4.0

srihari_sahu's picture

Anybody tried Angular 4.0 integration with Drupal 8?
Any ideas about integration with/without twig?

Angular In A block

taggartj's picture

This is great some times you Just want to use Angular in A block on your Drupal site I have made a boiler plate module to get you up and running quick.

https://www.drupal.org/sandbox/taggartj/2928776

Ps Thanks for the info on interpolateProvider i was scratching my head on that one for a bit.