Building A Content Management System Using The MEAN Stack - 7 (Front-End Development)

in #utopian-io6 years ago

Repository

https://github.com/nodejs/node

What Will I Learn

The codebase for this tutorial is based on MEANie an open source content management system by Jason Watmore.

This is the seventh in the series of tutorials on building a content management system using the MEAN technology.

In the last tutorial we created the pages, redirects and account view for the admin area.

In this tutorial we will work on the last service module needed for the admin area.

We will also work on all directives and filters needed for this application.

By the end of this tutorial we will have completed work on all the features for the admin section of the application.

N.B;- LINK TO THE EARLIER TUTORIALS IN THIS SERIES CAN BE FOUND AT THE END OF THIS POST

Requirements

Difficulty

  • Intermediate

Tutorial Contents

Services

Data Service

In the admin area of the CMS we have the following views

  • Posts
  • Pages
  • Redirects
  • Accounts

Each view has a service that interacts with the backend to extract data, all these service need a data service in the client side that will fetch and get all needed from the backend.

This data service will then provide all data needed by all other client side services.

We will create the data service in the services directory located in the admin directory.

Create a new file data.service.js and paste the code

(function () {
    'use strict';
    angular
        .module('app')
        .factory('DataService', Service);
    // generic data service to be used as base for other entity services
    function  Service($http, $q) {
        return  function (endPoint) {
            var  service  = {};
            service.GetAll  =  GetAll;
            service.GetById  =  GetById;
            service.Save  =  Save;
            service.Delete  =  Delete;
            return  service;
            
            function  GetAll() {
                return  $http.get(endPoint).then(handleSuccess, handleError);
            }

            function  GetById(id) {
                return  $http.get(endPoint  +  '/'  +  id).then(handleSuccess, handleError);
            }

            function  Save(entity) {
                if (entity._id) {
                    // update
                    return  $http.put(endPoint  +  '/'  +  entity._id, entity).then(handleSuccess, handleError);
                } else {
                    // create
                    return  $http.post(endPoint, entity).then(handleSuccess, handleError);
                }
            }

            function  Delete(id) {
                return  $http.delete(endPoint  +  '/'  +  id).then(handleSuccess, handleError);
            }
        }

        // private functions
        function  handleSuccess(res) {
            return  res.data;
        }
        
        function  handleError(res) {
            return  $q.reject(res.data  &&  res.data.Message);
        }
    }
})();

Data service contains the main function Service() which is the container function for all the other DataService methods.

DataService() firstly returns an object service which has the following methods

  • GetAll
  • GetbyId
  • Save
  • Delete

GetAll() returns the data gotten as the result of a http GET request to the endpoint specified.

GetById() returns the id of the data gotten as the result of a http GET request to the endpoint specified.

Save() has a parameter entity which represents a collection in the database.

The function checks if the collection already exists in the database by comparing ids.

If the collection exists the function updates data in the collection with new data provided else the function creates a new collection with the name stored in entity and saves the data provided in it.

Delete() has a parameter id representing the id of the endpoint specified in the database.

The function sends a DELETE request to the endpoint that has id that matches the one provided as parameter to the function.

Directives

Our application uses some extra features that requires special instructions to make them work the way we want them to.

We are going to issue special instructions for post tags

The special instructions will be stored in a directory directives in the admin directory.

Post Tags

In the directives directory add a new file tags.directive.js which will contain the directives for the post tags behavior.

In the tags.directive.js file paste the following code

(function () {
    'use strict';

    angular
        .module('app')
        .directive('tags', Directive);
        
    function  Directive($filter) {
        return {
            require:  'ngModel',
            link:  function (scope, element, attr, ngModel) {
                // convert to comma separated string for display
                ngModel.$formatters.push(function (tags) {
                    return  $filter('csv')(tags);
                });

                // convert to array for storage
                ngModel.$parsers.push(function (tagsString) {
                    var  tags  =  _.map(tagsString.split(','), function (tag) {
                        // trim any extra spaces
                        return  tag.trim();
                    });

                    // remove any empty tags
                    tags  =  _.filter(tags, function (tag) { return  tag; });
                    return  tags;
                });
            }
        };
    }
})();

Directive($filter) is the main function in the file and it returns an object which determines the behavior of the tags included in the posts.

require: 'ngModel' allows us access the controller for the ngModel directive.

The link() function contains parameters scope, element, attr which are requirements for any custom directive.

ngModel.$formatters.push() will format the post tags such that all post tags will be displayed with a comma separating one from the other using the csv filter which will be created later.

ngModel.$parsers.push() will convert all the inputted tags into an array to prepare for storage in the database.

Filters

In this section we will add the filters needed for some of the front end features to display correctly.

Create a new directory filters in the admin directory. We will add two filters including

  • CSV filter
  • Slugify filter
CSV Filter

In the filters directory add a new file csv.filter.js.

In the tags directive earlier we used the csv filter to add commas in between the tags.

The code for csv.filter.js

(function () {
    'use strict';

    angular
        .module('app')
        .filter('csv', Filter);
  
    function  Filter() {
        return  function (array) {
            if (!array)
                return;
            return  array.toString().replace(/,/g, ', ');
        };
    }
})();

The Filter() method will check if the tags are not stored in an array, if that condition is true then the function ends.

If the condition is false the function converts the contents of the array into string and all the cases where / can be found in the list of tags will be replaced with ,.

Slugify Filter

The slugify filter will format the display characteristics of the slugs included in the page and post details.

In the filters directory add a new file slugify.filter.js.

Paste the following code in the file

(function () {
    'use strict';
    
    angular
        .module('app')
        .filter('slugify', Filter);
  
    function  Filter() {
        return  function (input) {
            if (!input)
                return;
                
            // make lower case and trim
            var slug = input.toLowerCase().trim();

            // replace invalid chars with spaces
            slug  =  slug.replace(/[^a-z0-9\s-]/g, ' ');

            // replace multiple spaces or hyphens with a single hyphen
            slug  =  slug.replace(/[\s-]+/g, '-');

            return  slug;
        };
    }
})();

The Filter() method in this file firstly checks if there is an input to work on, if there isn't the function ends but if there is the function continues with the execution.

The value of input is then converted to lowercase and and trimmed of any whitespace. This new value is stored in the variable slug

All invalid characters in slug is then replaced with spaces.

And all spaces in slug is then replaced with hyphens.

We have completed work on the admin section of the application, in the next tutorial we will start work on the front end view of the blog section of the application.

Curriculum

  1. Building A Content Management System Using The MEAN Stack - 1 (Create Server, Config File and Helper Modules)

  2. Building A Content Management System Using The MEAN Stack - 2(Create Controller Modules 1)

  3. Building A Content Management System Using The MEAN Stack - 3 (Create Controller Modules 2)

  4. Building A Content Management System Using The MEAN Stack - 4 (Create Services Modules)

  5. Building A Content Management System Using The MEAN Stack - 5 (Front-End Development)

  6. Building A Content Management System Using The MEAN Stack - 6 (Front-End Development)

Proof Of Work Done

https://github.com/olatundeee/mean-cms

Sort:  

Thank you for your contribution @gotgame.
After analyzing your tutorial we suggest the following points:

  • We suggest you put images of what is being developed. Images makes the tutorial more interesting.

  • Put the title with more keywords, such as NodeJS and Angular.

The code is very well explained and quite simple. Good job!

Your contribution has been evaluated according to Utopian policies and guidelines, as well as a predefined set of questions pertaining to the category.

To view those questions and the relevant answers related to your post, click here.


Need help? Write a ticket on https://support.utopian.io/.
Chat with us on Discord.
[utopian-moderator]

Thank you for your review, @portugalcoin!

So far this week you've reviewed 8 contributions. Keep up the good work!

Hi @gotgame!

Your post was upvoted by @steem-ua, new Steem dApp, using UserAuthority for algorithmic post curation!
Your post is eligible for our upvote, thanks to our collaboration with @utopian-io!
Feel free to join our @steem-ua Discord server

Hello, as a member of @steemdunk you have received a free courtesy boost! Steemdunk is an automated curation platform that is easy to use and built for the community. Join us at https://steemdunk.xyz

Upvote this comment to support the bot and increase your future rewards!

Hey, @gotgame!

Thanks for contributing on Utopian.
We’re already looking forward to your next contribution!

Get higher incentives and support Utopian.io!
Simply set @utopian.pay as a 5% (or higher) payout beneficiary on your contribution post (via SteemPlus or Steeditor).

Want to chat? Join us on Discord https://discord.gg/h52nFrV.

Vote for Utopian Witness!

Coin Marketplace

STEEM 0.19
TRX 0.15
JST 0.029
BTC 63914.63
ETH 2664.93
USDT 1.00
SBD 2.77