Cosmic JS Blog Stay tuned for community news, company announcements and updates from the Cosmic JS team.

How to Build an Emoji Game Using AngularJS


In this tutorial I'm going to show you how to create a "Emoji" game using a little bit of Node, and Cosmic JS. For the sake of understanding how to consume Restful API’s, this tutorial will show how to make simple AJAX requests to the Cosmic JS API in order to retrieve, update, and delete data in our Cosmic JS Buckets. Let's get started.

TL;DR

Download the GitHub repo.
Check out the demo.

Getting Started:

First, let’s make a new directory to build our project in and lets also make a package.json file.

mkdir emoji-app
emoji-app$ touch package.json

Now, in your package.json, copy and paste the code below:

//emoji-app/package.json
{
  "name": "emoji-app",
  "version": "1.0.0",
  "main": "app-server.js",
  "engines": {
    "node": "4.1.2",
    "npm": "3.5.2"
  },
  "description": "",
  "dependencies": {
    "body-parser": "^1.17.2",
    "bower": "^1.7.7",
    "buffer-to-vinyl": "^1.1.0",
    "express": "^4.13.3",
    "gulp": "^3.9.1",
    "gulp-autoprefixer": "^3.1.0",
    "gulp-concat": "^2.6.0",
    "gulp-concat-css": "^2.2.0",
    "gulp-env": "^0.4.0",
    "gulp-minify-css": "^1.2.4",
    "gulp-ng-config": "^1.4.0",
    "gulp-npm-script-sync": "^1.1.0",
    "gulp-webserver": "^0.9.1",
    "http-server": "^0.9.0",
    "stripe": "^4.22.0",
    "wiredep": "^3.0.0"
  },
  "scripts": {
    "postinstall": "bower install && gulp config && gulp js",
    "start": "npm run production",
    "production": "node app-server.js",
    "gulp": "gulp"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "gulp-npm-script-sync": "^1.1.0",
    "gulp-remote-src": "^0.4.2"
  }
}/
            

Second, let’s make a bower.json file.

emoji-app$ touch bower.json

Now, in your bower.json, copy and paste the code below:

//emoji-app/bower.json
{
  "name": "emoji-app",
  "description": "Emoji App",
  "version": "0.0.0",
  "homepage": "https://github.com/kutsaniuk/emoji-app",
  "license": "MIT",
  "private": true,
  "dependencies": {
    "angular": "~1.5.x",
    "angular-mocks": "~1.5.x",
    "angular-bootstrap": "~1.1.x",
    "angular-cookies": "~1.5.x",
    "angular-route": "~1.5.x",
    "angular-ui-router": "0.2.x",
    "angular-resource": "1.5.x",
    "angular-animate": "~1.5.x",
    "ng-dialog": "0.6.1",
    "bootstrap": "3.3.x",
    "cr-acl": "",
    "angular-chosen-localytics": "*",
    "bootstrap-chosen": "*",
    "ng-flow": "^2.7.4",
    "angular-mask": "*",
    "checklist-model": "0.9.0",
    "angular-ui-notification": "^0.2.0",
    "angular-ui-calendar": "^1.0.2",
    "angular-ui-switch": "^0.1.1",
    "ng-scrollbars": "^0.0.11",
    "jquery.scrollbar": "*",
    "angular-flash-alert": "^2.4.0",
    "components-font-awesome": "^4.7.0",
    "angular-loading-bar": "^0.9.0",
    "angular-environment": "^1.0.8",
    "angular-emoji-popup": "",
    "angular-dragdrop": "",
    "angular-sanitize": "1.5.*",
    "angular-drag-and-drop-directives": "",
    "jquery-ui-touch-punch": "",
    "angular-touch":"1.5.*",
    "textAngular":"1.5.*"
  },
  "resolutions": {
    "angular": "~1.5.x"
  },
  "devDependencies": {
    "cr-acl": "^0.5.0"
  }
}
            

Config app server:

emoji-app$ touch app-server.js
//events-app/app-server.js
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
app.set('port', process.env.PORT || 3000)
app.use(express.static(__dirname))
app.use(bodyParser.json())
var http = require('http').Server(app)
// Route
app.get('/', (req, res) => {
  res.sendFile(__dirname + '/index.html');
})
http.listen(app.get('port'), () => {
  console.log('Emoji App listening on ' + app.get('port'))
})
            

What we're installing and why:

  1. We're going to use the AngularJS framework to build Single-page application
  2. We're installing angular-ui-router for create multi views.
  3. We are going to use gulp for build all js and css files into one file.

Building our app:

Now we're going to build out our file structure a bit more so that we can organize our angular modules and js files. This is what our emoji-app directory should look like:

emoji-app
|----app
|       |----auth
|                 |----auth.ctrl.js
|                 |----auth.service.js
|       |----config
|                 |----config.js
|       |----watch
|                 |----profile
|                           |----watch.profile.ctrl.js
|                           |----watch.profile.mdl.js
|                 |----watch.ctrl.js
|                 |----watch.mdl.js
|                 |----watch.service.js
|       |----admin
|                 |----authors
|                           |----add
|                                   |----admin.authors.add.ctrl.js
|                                   |----admin.authors.add.mdl.js
|                           |----edit
|                                   |----admin.authors.edit.ctrl.js
|                                   |----admin.authors.edit.mdl.js
|                           |----admin.authors.ctrl.js
|                           |----admin.authors.mdl.js
|                           |----admin.authors.service.js
|                 |----quotes
|                           |----add
|                                   |----admin.quotes.add.ctrl.js
|                                   |----admin.quotes.add.mdl.js
|                           |----edit
|                                   |----admin.quotes.edit.ctrl.js
|                                   |----admin.quotes.edit.mdl.js
|                           |----admin.quotes.ctrl.js
|                           |----admin.quotes.mdl.js
|                           |----admin.quotes.service.js
|                 |----admin.ctrl.js
|                 |----admin.mdl.js
|       |----author
|                 |----author.ctrl.js
|                 |----author.mdl.js
|       |----emoji
|                 |----emoji.ctrl.js
|                 |----emoji.mdl.js
|                 |----emoji.service.js
|       |----user
|                 |----user.service.js
|       |----main.mdl.js
|----dist
|       |----css
|       |----img
|       |----js
|----css
|----views
|----resources
|----gulpfile.js
|----app-server.js
|----bower.json
|----package.json
            

Now we we will set up our index.html. Copy and paste the following code into your index.html file:

<!DOCTYPE html>
<html lang="en" ng-app="main">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="">

    <title>Emoji App</title>

    <!-- bower:css -->
    <!-- endbower -->

    <!-- Bootstrap Core CSS -->
    <link href="bower_components/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">

    <!-- Custom CSS -->

    <link href="dist/css/main.min.css" rel="stylesheet">


    <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>
    <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
    <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
    <![endif]-->

</head>
<body>

<div ui-view></div>

<!-- bower:js -->
<!-- endbower -->

<script src="dist/js/main.js"></script>
</body>
</html>
            

Here, we are going to target our "root" view to place our angular modules in later. The main.js file located in our dist directory is what our gulpfile.js file will spit out after bundling all of our angular modules Now, set up our gulpfile.js file to bundle all of our js files and export that bundle file to our dist directory. Copy the following code into your gulpfile.js file:

//emoji-app/gulpfile.js
'use strict';

var gulp = require('gulp'),
    webserver = require('gulp-webserver'),
    minifyCSS = require('gulp-minify-css'),
    concat = require('gulp-concat'),
    wiredep = require('wiredep').stream,
    gulpNgConfig = require('gulp-ng-config'),
    autoprefixer = require('gulp-autoprefixer'),
    b2v = require('buffer-to-vinyl'),
    sync = require('gulp-npm-script-sync');

sync(gulp);

gulp.task('css', function () {
  return gulp.src('css/**/*.css')
    .pipe(minifyCSS())
    .pipe(concat('main.min.css'))
    .pipe(autoprefixer())
    .pipe(gulp.dest('dist/css'));
});

gulp.task('js', function() {
    return gulp.src('app/**/**/*.js')
        .pipe(concat('main.js'))
        .pipe(gulp.dest('dist/js/'));
});

gulp.task('config', function () {
    const json = JSON.stringify({
        BUCKET_SLUG: process.env.COSMIC_BUCKET,
        MEDIA_URL: 'https://api.cosmicjs.com/v1/' + process.env.COSMIC_BUCKET + '/media',
        URL: 'https://api.cosmicjs.com/v1/',
        READ_KEY: process.env.COSMIC_READ_KEY || '',
        WRITE_KEY: process.env.COSMIC_WRITE_KEY || '',
        DEFAULT_IMAGE: process.env.DEFAULT_IMAGE || ''
    });
    return b2v.stream(new Buffer(json), 'config.js')
        .pipe(gulpNgConfig('config'))
        .pipe(gulp.dest('app/config'));
});

gulp.task('default', function () {
  gulp.watch('css/**/*.css', ['css']);
  gulp.watch('app/**/**/*.js', ['js']);
  gulp.watch('bower.json', ['bower']);
});

gulp.task('bower', function () {
  gulp.src('index.html')
    .pipe(wiredep({
      directory: 'bower_components'
    }))
    .pipe(gulp.dest(''));
});

            

After that we can create main module. Copy and paste the following code into your main.mdl.js file:

(function () {
    'use strict';

    angular
        .module('main', [
            'ui.router',
            'ui.bootstrap',
            'ngMask',
            'ngCookies',
            'ngRoute',
            'ngDialog',
            'cr.acl',
            'ui-notification',
            'ngFlash',
            'ngAnimate',
            'textAngular',
            'flow',
            'angular-loading-bar',
            'ngDragDrop',
            'ngEmoticons',
            'ngSanitize',
            'ngTouch',

            'emoji',
            'admin',
            'author',

            'config'
        ])
        .config(config)
        .run(run);

    config.$inject = ['$stateProvider', '$urlRouterProvider', 'cfpLoadingBarProvider', 'NotificationProvider'];
    function config($stateProvider, $urlRouterProvider, cfpLoadingBarProvider, NotificationProvider) {
        cfpLoadingBarProvider.includeSpinner = false;

        NotificationProvider.setOptions({
            startTop: 25,
            startRight: 25,
            verticalSpacing: 20,
            horizontalSpacing: 20,
            positionX: 'right',
            positionY: 'bottom'
        });

        $urlRouterProvider.otherwise(function ($injector) {
            var $state = $injector.get("$state");
            var $location = $injector.get("$location");
            var crAcl = $injector.get("crAcl");

            var state = "";

            switch (crAcl.getRole()) {
                case 'ROLE_ADMIN':
                    state = 'admin.authors';
                    break;
                default : state = 'main.emoji';
            }

            if (state) $state.go(state);
            else $location.path('/');
        });

        $stateProvider
            .state('main', {
                url: '/',
                abstract: true,
                templateUrl: '../views/main.html',
                // controller: 'CartCtrl as cart',
                data: {
                    is_granted: ['ROLE_GUEST']
                }
            })
            .state('blog', {
                url: '/blog',
                templateUrl: '../blog.html'
            })
            .state('auth', {
                url: '/login',
                templateUrl: '../views/auth/login.html',
                controller: 'AuthCtrl as auth',
                onEnter: ['AuthService', 'crAcl', function(AuthService, crAcl) {
                    AuthService.clearCredentials();
                    crAcl.setRole();
                }],
                data: {
                    is_granted: ['ROLE_GUEST']
                }
            });
    }

    run.$inject = ['$rootScope', '$cookieStore', '$state', 'crAcl'];
    function run($rootScope, $cookieStore, $state, crAcl) {
        // keep user logged in after page refresh
        $rootScope.globals = $cookieStore.get('globals') || {};

        crAcl
            .setInheritanceRoles({
                'ROLE_ADMIN': ['ROLE_ADMIN', 'ROLE_GUEST'],
                'ROLE_GUEST': ['ROLE_GUEST']
            });

        crAcl
            .setRedirect('main.emoji');

        if ($rootScope.globals.currentUser) {
            crAcl.setRole($rootScope.globals.currentUser.metadata.role);
            // $state.go('admin.watches');
        }
        else {
            crAcl.setRole();
        }

    }
    angular.module('main')
        .directive('compile', ['$compile', function ($compile) {
            return function (scope, element, attrs) {
                scope.$watch(
                    function (scope) {
                        // watch the 'compile' expression for changes
                        return scope.$eval(attrs.compile);
                    },
                    function (value) {
                        element.html(value);

                        $compile(element.contents())(scope);
                    }
                );
            };
        }]);
})();
             

Now we we will set up our Auth Controller. Copy and paste the following code into your auth.ctrl.js file:

(function () {
    'use strict';

    angular
        .module('main')
        .controller('AuthCtrl', AuthCtrl);

    function AuthCtrl(crAcl, $state, AuthService, Flash, $log) {
        var vm = this;

        vm.login = login;

        vm.loginForm = null;

        vm.credentials = {};
        vm.user = {};

        function login(credentials) {
            function success(response) {
                function success(response) {
                    if (response.data.status !== 'empty') {
                        var currentUser = response.data.objects[0];

                        crAcl.setRole(currentUser.metadata.role);
                        AuthService.setCredentials(currentUser);
                        $state.go('admin.authors');
                    }
                    else
                        Flash.create('danger', 'Incorrect username or password');
                }

                function failed(response) {
                    $log.error(response);
                }

                if (response.data.status !== 'empty')
                    AuthService
                        .checkPassword(credentials)
                        .then(success, failed);
                else
                    Flash.create('danger', 'Incorrect username or password');

                $log.info(response);
            }

            function failed(response) {
                $log.error(response);
            }

            if (vm.loginForm.$valid)
                AuthService
                    .checkUsername(credentials)
                    .then(success, failed);
        }

    }
})();
            

Create Auth Service, copy and paste the code below:

(function () {
    'use strict';

    angular
        .module('main')
        .service('AuthService', function ($http,
                                          $cookieStore,
                                          $q,
                                          $rootScope,
                                          URL, BUCKET_SLUG, READ_KEY, WRITE_KEY) {
            var authService = this;
            $http.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';

            authService.checkUsername = function (credentials) {
                return $http.get(URL + BUCKET_SLUG + '/object-type/users/search', {
                    params: {
                        metafield_key: 'email',
                        metafield_value_has: credentials.email,
                        limit: 1,
                        read_key: READ_KEY
                    }
                });
            };
            authService.checkPassword = function (credentials) {
                return $http.get(URL + BUCKET_SLUG + '/object-type/users/search', {
                    ignoreLoadingBar: true,
                    params: {
                        metafield_key: 'password',
                        metafield_value: credentials.password,
                        limit: 1,
                        read_key: READ_KEY
                    }
                });
            };
            authService.setCredentials = function (user) {
                $rootScope.globals = {
                    currentUser: user
                };

                $cookieStore.put('globals', $rootScope.globals);
            };
            authService.clearCredentials = function () {
                var deferred = $q.defer();
                $cookieStore.remove('globals');

                if (!$cookieStore.get('globals')) {
                    $rootScope.globals = {};
                    deferred.resolve('Credentials clear success');
                } else {
                    deferred.reject('Can\'t clear credentials');
                }

                return deferred.promise;
            };
        });
})();
            

What's going on here:

  1. We are using the ui-router for config routes.
  2. We created Auth Service for our asynchronous calls to our Cosmic JS API.
  3. We created Auth Controller for checking credentials.

Create User Service for get and update User, copy and paste the code below:

(function () {
    'use strict';

    angular
        .module('main')
        .service('UserService', function ($http,
                                          $cookieStore,
                                          $q,
                                          $rootScope,
                                          URL, BUCKET_SLUG, READ_KEY, WRITE_KEY) {
            $http.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';

            this.getCurrentUser = function (ignoreLoadingBar) {
                return $http.get(URL + BUCKET_SLUG + '/object/' + $rootScope.globals.currentUser.slug, {
                    ignoreLoadingBar: ignoreLoadingBar,
                    params: {
                        read_key: READ_KEY
                    }
                });
            };
            this.getUser = function (slug, ignoreLoadingBar) {
                return $http.get(URL + BUCKET_SLUG + '/object/' + slug, {
                    ignoreLoadingBar: ignoreLoadingBar,
                    params: {
                        read_key: READ_KEY
                    }
                });
            };
            this.updateUser = function (user) {
                user.write_key = WRITE_KEY;

                return $http.put(URL + BUCKET_SLUG + '/edit-object', user, {
                    ignoreLoadingBar: false
                });
            };

        });
})();
            

Create Emoji Service for get emoji from words, copy and paste the code below:

(function () {
    'use strict';

    angular
        .module('main')
        .service('EmojiService', function ($http) {

            var that = this;

            that.Quote = function (text, author, slug) {
                this.text = text;
                this.author = author;
                this.slug = slug;
            };

            that.Emoji = function (code, position) {
                this.code = code;
                this.position = position;
            };

            that.Container = function (type, item) {
                this.type = type;
                this.item = item;
            };

            that.Random = {
                randNumOld: 0,
                getRandomInt: function (min, max) {
                    var randNum = Math.floor(Math.random() * (max - min + 1)) + min;
                    if (randNum == this.randNumOld) return this.getRandomInt(min, max);
                    this.randNumOld = randNum;

                    return randNum;
                }
            };

            this.getEmojisFromWords = function (quote) {
                var words = [];
                var word = '';

                quote += " ";

                for (var i = 0; i < quote.length; i++) {
                    if (quote[i] !== ' ') word += quote[i];
                    else {
                        words.push(word);
                        word = '';
                    }
                }

                for (var j = 0; j < words.length; j++) {
                    if (getMeAnEmoji(words[j]) !== "") words[j] = ":" + getMeAnEmoji(words[j]) + ":";
                }

                console.log(words);
                return words;
            };

            this.getEmoji = function (quote, emojis, containers, checkAnswers) {
                var i = 0;
                var position = 0;
                var result;
                var word = '';
                var isEmoji = new RegExp(":");
                var _quote = quote;

                while (i < quote.text.length) {
                    if (isEmoji.test(quote.text[i])) {
                        result = ( /\:(\w+)\:/.exec(quote.text) )[1];
                        emojis.push(new that.Emoji(":" + result + ":", i));
                        containers.push(new that.Container('emoji', []));
                        checkAnswers.push(new that.Emoji(":" + result + ":", position));

                        quote.text[i] = quote.text[i].replace(':' + result + ':', '_emoji_');

                        position++;
                    }
                    else {
                        containers.push(new that.Container('word', quote.text[i]));
                    }
                    word = '';
                    i++;
                }

                $http.get('/resources/emojis.json')
                    .success(function (data) {
                        for (var j = 0; j < 3; j++) {
                            emojis.push(new that.Emoji(":" + data[parseInt(Math.random() * data.length)] + ":"));
                        }
                    });

                return _quote;
            };

        });
})();
            

Create Emoji Controller for get quotes and checking results, copy and paste the code below:

(function () {
    'use strict';

    angular
        .module('main')
        .controller('EmojiCtrl', EmojiCtrl);

    function EmojiCtrl($scope, DEFAULT_IMAGE, EmojiService, AdminQuotesService, $log) {
        var vm = this;

        vm.checkAnswers = [];
        vm.quote = {};
        vm.quotes = [];
        vm.emojis = [];
        vm.containers = [];
        vm.win = false;

        vm.DEFAULT_IMAGE = DEFAULT_IMAGE;

        var random = EmojiService.Random;
        var getEmojisFromWords = EmojiService.getEmojisFromWords;
        var getEmoji = EmojiService.getEmoji;
        var Quote = EmojiService.Quote;
        var Emoji = EmojiService.Emoji;

        var getRandomQuote = _getRandomQuote;
        var getUserAnswers = _getUserAnswers;

        vm.getUserAnswerLength = getUserAnswerLength;
        vm.nextQuote = nextQuote;
        vm.checkAnswer = checkAnswer;
        vm.getUserAnswerLength = getUserAnswerLength;

        $scope.getOptionsContainer = getOptionsContainer;

        function _getRandomQuote(quotes) {
            var _random = random.getRandomInt(0, quotes.length - 1);
            console.log(quotes[_random]);
            return quotes[_random].slug;
        }

        function _getUserAnswers(containers) {
            var userAnswers = [];
            var position = 0;

            for (var i = 0; i < containers.length; i++) {

                if (!Array.isArray(containers[i].item)) continue;
                userAnswers.push(new Emoji(containers[i].item[0].code, position));
                position++;

            }

            return userAnswers;
        }

        function getUserAnswerLength() {
            var userAnswersLength = 0;

            for (var k = 0; k < vm.containers.length; k++) {
                if (!Array.isArray(vm.containers[k].item)) continue;
                if (vm.containers[k].item.length !== 0) userAnswersLength += 1;
            }
            return userAnswersLength;
        }

        function nextQuote() {
            getQuote(getRandomQuote(vm.quotes));
        }

        function checkAnswer() {
            var result = [];
            var position = 0;

            function in_array(value, array) {
                for (var i = 0; i < array.length; i++) {
                    if (array[i] == value) return true;
                }
                return false;
            }

            if (vm.getUserAnswerLength() === vm.checkAnswers.length) {
                var userAnswers = getUserAnswers(vm.containers);
                for (var j = 0; j < userAnswers.length; j++) {
                    vm.checkAnswers[j].code === userAnswers[j].code ? result.push(true) : result.push(false);
                }

                console.log(result);

                for (var i = 0; i < vm.containers.length; i++) {

                    if (!Array.isArray(vm.containers[i].item)) continue;
                    if (!result[position]) {
                        vm.emojis[vm.containers[i].item[0].jqyoui_pos] = new Emoji(vm.containers[i].item[0].code, i);
                        vm.containers[i].item.splice(0, 1);
                    }
                    position++;

                }

                console.log(vm.emojis);
                !in_array(false, result) ? vm.win = true : vm.win = false;
            }
        }

        function getOptionsContainer(container) {
            return {
                accept: function (dragEl) {
                    if (container.length >= 1) {
                        return false;
                    } else {
                        return true;
                    }
                }
            }
        }

        function getQuotes() {
            function success(response) {
                response.data.objects.forEach(function (quote) {
                    vm.quotes.push(
                        new Quote(
                            getEmojisFromWords(quote.metadata.text),
                            quote.metadata.author,
                            quote.slug
                        )
                    );
                });
                $log.info(vm.quotes);

                getQuote(getRandomQuote(vm.quotes));

            }

            function failed(response) {
                $log.error(response);
            }

            AdminQuotesService
                .getQuotes(true)
                .then(success, failed);
        }

        function getQuote(slug) {
            function success(response) {
                vm.quote = new Quote(
                    getEmojisFromWords(response.data.object.metadata.text),
                    response.data.object.metadata.author,
                    response.data.object.slug
                );

                vm.emojis = [];
                vm.containers = [];
                vm.checkAnswers = [];
                vm.win = false;

                getEmoji(
                    vm.quote,
                    vm.emojis,
                    vm.containers,
                    vm.checkAnswers
                );

                vm.emojis.sort(function (a, b) {
                    return a.code.charCodeAt(1) - b.code.charCodeAt(2)
                });

                vm.emojis.reverse();
                console.log('emojis', vm.emojis);
            }

            function failed(response) {
                $log.error(response);
            }

            AdminQuotesService
                .getQuoteBySlug(slug)
                .then(success, failed);
        }

        getQuotes();

        $('.emoji').draggable(); // FOR TouchScreen
    }
})();
            

Create Emoji Module, copy and paste the code below:

(function () {
    'use strict';

    angular
        .module('emoji', [])
        .config(config);

    config.$inject = ['$stateProvider', '$urlRouterProvider'];
    function config($stateProvider, $urlRouterProvider) {

        $stateProvider
            .state('main.emoji', {
                url: '',
                templateUrl: '../views/emoji/emoji.html',
                controller: 'EmojiCtrl as emojiCtrl'
            });
    }
})();
            

What's going on here:

  1. We created Emoji Service for get emoji from words.
  2. We created Emoji Controller for drag and drop emoji, get quotes and checking results.
  3. We created Emoji Module.

Create Author Controller for getting information of author, copy and paste the code below:

(function () {
    'use strict';

    angular
        .module('main')
        .controller('AuthorCtrl', AuthorCtrl);

    function AuthorCtrl($stateParams, $scope, DEFAULT_IMAGE, AdminAuthorsService, Flash, $log) {
        var vm = this;

        vm.author = {};

        vm.DEFAULT_IMAGE = DEFAULT_IMAGE;

        getAuthor($stateParams.slug);

        function getAuthor(slug) {
            function success(response) {
                response.data.object.metadata.born = new Date(response.data.object.metafields[2].value);
                response.data.object.metadata.died = new Date(response.data.object.metafields[3].value);
                vm.author = response.data.object;
            }

            function failed(response) {
                $log.error(response);
            }

            AdminAuthorsService
                .getAuthorBySlug(slug)
                .then(success, failed);
        }
    }
})();

Create Author Module, copy and paste the code below:

(function () {
    'use strict';

    angular
        .module('author', [])
        .config(config);

    config.$inject = ['$stateProvider', '$urlRouterProvider'];
    function config($stateProvider, $urlRouterProvider) {

        $stateProvider
            .state('main.author', {
                url: 'author/:slug',
                templateUrl: '../views/author/author.html',
                controller: 'AuthorCtrl as vm',
                data: {
                    is_granted: ['ROLE_GUEST']
                }
            });
    }
})();

What's going on here:

  1. We can see information about authors.

Conclusion:

We were able to consume the Cosmic JS API with our actions and dispatcher functions. I hope you enjoyed this tutorial as much as I did, if you have any questions reach out to us on Twitter and join our community on Slack.

You may also like


Cosmic JS is on a mission to help you build apps faster.  And with that goal in mind, we're happy to announce some additions to our API that will help you manage your application content faster and easier, right from the Cosmic JS API.

If you’re a developer and need to open up a new blog for yourself or a client, the idea of using Wordpress probably makes you cringe.

We sat down with Jason Price for our latest installment of the Cosmic JS Developer Spotlight Series. 

In this tutorial I’m going to show you how to build a user management app using Node.js and the Cosmic JS CMS API.

We are happy to announce that you can now add automatically backup your Buckets via the Automatic Daily Backups Add-on.  To add the peace of mind of daily Backups, go to Your Bucket Dashboard > Settings > Backups.

We are happy to let you know that now have a Markdown Metafield to use in your Cosmic JS Objects.