GithubHelp home page GithubHelp logo

angular-app's Introduction

Build Status

AngularJS CRUD application demo


Purpose

The idea is to demonstrate how to write a typical, non-trivial CRUD application using AngularJS. To showcase AngularJS in its most advantageous environment we've set out to write a simplified project management tool supporting teams using the SCRUM methodology. The sample application tries to show best practices when it comes to: folders structure, using modules, testing, communicating with a REST back-end, organizing navigation, addressing security concerns (authentication / authorization).

This sample application is featured in our book where you can find detailed description of the patterns and techniques used to write this code:

We've learned a lot while using and supporting AngularJS on the mailing list and would like to share our experience.

Stack

Build

It is a complete project with a build system focused on AngularJS apps and tightly integrated with other tools commonly used in the AngularJS community:

Installation

Platform & tools

You need to install Node.js and then the development tools. Node.js comes with a package manager called npm for installing NodeJS applications and libraries.

  • Install node.js (requires node.js version >= 0.8.4)

  • Install Grunt-CLI and Karma as global npm modules:

    npm install -g grunt-cli karma
    

(Note that you may need to uninstall grunt 0.3 globally before installing grunt-cli)

Get the Code

Either clone this repository or fork it on GitHub and clone your fork:

git clone https://github.com/angular-app/angular-app.git
cd angular-app

App Server

Our backend application server is a NodeJS application that relies upon some 3rd Party npm packages. You need to install these:

  • Install local dependencies (from the project root folder):

    cd server
    npm install
    cd ..
    

    (This will install the dependencies declared in the server/package.json file)

Client App

Our client application is a straight HTML/Javascript application but our development process uses a Node.js build tool Grunt.js. Grunt relies upon some 3rd party libraries that we need to install as local dependencies using npm.

  • Install local dependencies (from the project root folder):

    cd client
    npm install
    cd ..
    

    (This will install the dependencies declared in the client/package.json file)

Building

Configure Server

The server stores its data in a MongoLab database.

  • Create an account at MongoLab - it's free: [https://mongolab.com/signup/].

  • Create a database to use for this application: [https://mongolab.com/create]

  • Grab your API key: [https://mongolab.com/user?username=YOUR_USERNAME_HERE]

  • Edit server/config.js to set your MongoLab API Key and the name of the database you created.

    mongo: {
        dbUrl: 'https://api.mongolab.com/api/1',    // The base url of the MongoLab DB server
        apiKey: 'YOUR_API_KEY_HERE',                // Our MongoLab API key
    },
    security: {
        dbName: 'YOUR_DB_NAME_HERE',                // The name of database that contains the security information
        usersCollection: 'users'                    // The name of the collection contains user information
    },
    
  • Optionally change the name of admin user in server/lib/initDB.js. The default is 'Admin' ([email protected] : changeme).

    var initDB = {
      adminUser: { email: '[email protected]', password: 'changeme', admin: true, firstName: 'Admin', lastName: 'User' },
    });
    // Note the user information, including password, are stored as plain text in the MongoLab database.
    
  • Run our initialization script to initialize the database with a first admin user ([email protected] : changeme).

    node server/initDB.js
    

Configure Client

The client specifies the name of the MongoDB to use in client/src/app/app.js. If your DB is not called "ascrum" then you need to change the MONGOLAB_CONFIG constant:

angular.module('app').constant('MONGOLAB_CONFIG', {
  baseUrl: '/databases/',
  dbName: 'ascrum'
});

Build the client app

The app made up of a number of javascript, css and html files that need to be merged into a final distribution for running. We use the Grunt build tool to do this.

  • Build client application:

    cd client
    grunt build
    cd ..
    

It is important to build again if you have changed the client configuration as above.

Running

Start the Server

  • Run the server

    cd server
    node server.js
    cd ..
    
  • Browse to the application at [http://localhost:3000]

  • Login with the admin user as defined in server/lib/initDB.js.

Browser Support

We only regularly test against Chrome 29 and occasionally against Firefox and Internet Explorer. The application should run on most modern browsers that are supported by the AngularJS framework. Obviously, if you chose to base your application on this one, then you should ensure you do your own testing against browsers that you need to support.

Development

Folders structure

At the top level, the repository is split into a client folder and a server folder. The client folder contains all the client-side AngularJS application. The server folder contains a very basic Express based webserver that delivers and supports the application. Within the client folder you have the following structure:

  • node_modules contains build tasks for Grunt along with other, user-installed, Node packages
  • dist contains build results
  • src contains application's sources
  • test contains test sources, configuration and dependencies
  • vendor contains external dependencies for the application

Default Build

The default grunt task will build (checks the javascript (lint), runs the unit tests (test:unit) and builds distributable files) and run all unit tests: grunt (or grunt.cmd on Windows). The tests are run by karma and need one or more browsers open to actually run the tests.

  • cd client
  • grunt
  • Open one or more browsers and point them to [http://localhost:8080/__test/]. Once the browsers connect the tests will run and the build will complete.
  • If you leave the browsers open at this url then future runs of grunt will automatically run the tests against these browsers.

Continuous Building

The watch grunt task will monitor the source files and run the default build task every time a file changes: grunt watch.

Build without tests

If for some reason you don't want to run the test but just generate the files - not a good idea(!!) - you can simply run the build task: grunt build.

Building release code

You can build a release version of the app, with minified files. This task will also run the "end to end" (e2e) tests. The e2e tests require the server to be started and also one or more browsers open to run the tests. (You can use the same browsers as for the unit tests.)

  • cd client
  • Run grunt release
  • Open one or more browsers and point them to [http://localhost:8080/__test/]. Once the browsers connect the tests will run and the build will complete.
  • If you leave the browsers open at this url then future runs of grunt will automatically run the tests against these browsers.

Continuous testing

You can have grunt (karma) continuously watch for file changes and automatically run all the tests on every change, without rebuilding the distribution files. This can make the test run faster when you are doing test driven development and don't need to actually run the application itself.

  • cd client
  • Run grunt test-watch.
  • Open one or more browsers and point them to [http://localhost:8080/__test/].
  • Each time a file changes the tests will be run against each browser.

angular-app's People

Contributors

buberdds avatar cironunes avatar dopry avatar dotbits avatar elnur avatar et avatar girasquid avatar hashplus avatar hjast avatar jan-molak avatar johnnyoshika avatar mickaelbaye avatar mohsen1 avatar nathasm avatar petebacondarwin avatar pkozlowski-opensource avatar rgaskill avatar saelfaer avatar witoldsz avatar wok avatar yehudab avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

angular-app's Issues

Wrong instruction for starting server

The following instruction:

Run the server with node server/server.js

should be updated to:

cd server
node server.js

If starting the server following the current instruction, the path '../client/dist' will not work.

Menu doesn't work on IE

Discovered yesterday (not surprising since we didn't test much on IE). When you log in and click on a menu item you will get signed out. I think this is due to the fact that IE doesn't play nicely with html5 routes. So we really need a way of using the same URLs for both the html5 and the hashbang mode.

In the longer run we should build up e2e tests suite and get IE verification "for free".

Change CRUDScopeMixIn

from being a constructor function to a being a factory function (returning object mix-in as a return value and not requiring using the new operator).

explain reasons to use angular-app over angular-seed

I just stumbled on angular-app after investing some time in an angular-seed-based Angular app, and now I'm wondering if I should have used angular-app instead. After a super quick look, It seems like angular-app has some more good stuff built in to facilitate development such as grunt and recess, but also has stuff like auth built in which wouldn't be appropriate for projects that don't need it. (Even recess would not be useful for those who prefer Compass.) It'd be helpful to have a section of the readme explaining how this differs from angular-seed and which use cases it's targeting.

Switch to using html5 routes

Depends on #14.

We might need to add a $navigation service (name to be decided) that would allow us to remove paths as strings from both templates and controllers.

Add unit tests for the classes checked-in so far

There are number of classes in the repository without unit tests. Let's add missing tests, starting with critical pieces (libs: CRUD mixin, mongolab, services, directives etc.) and work toward covering controllers as well (should be easy provided CRUD mixing is well tested).

Improve the 'release' task

Problems with the release task:

  • It doesn't concatenate files (didn't test, just from looking at the code)
  • Has task spec duplication with the build task

Ideally it could look like: build e2e.

Once again, didn't test those commands so might be missing something :-)

Introduce e2e tests

Setup e2e tests that would run:

  • as part of the local Grunt build
  • as part of Travis-CI build

Add application-wide error msg service

In case we need to report errors we shouldn't be returning error strings since those are not localized. We should have a service that holds all the error codes and is able to resolve a localized error message based on an error code (plus some arguments).

Add ability to sign-in at any time

by adding a login button somewhere in a header. Clicking on this button should open the login modal.

Unfortunately with today's implementation I don't know how to do it other than broadcasting an event (auth required).

Improve breadcrumbs

Currently we are showing Mongo ids in the breadcrumbs, this doesn't look. It is an interesting conceptual problem as well linked to the routing system.

Waiting for http download

I think we need to make the waiting status bar that pops up at the top more clever.

This is particularly noticeable when you type in an email address of a new user - the app goes off and checks that it is unique and pops up that blue banner, moving all the html down.

You talked about having named waits or something? Currently the HTTPRequestTracker simply counts pending requests. I think we could do something with directive that takes the name of a kind of request and can subscribe to an event when that request completes.

Make it easier to get started...

With the renewed interest in the project due to us "coming out of the closet!" I would like to make things easier for people to get started.

First I would like to bring the server back into the project. Both projects are closely linked and rely on each other. Merging them would make it easier to e2e test and also to correlate changes between the two projects.

Second, we need to write something for to initialize a blank database. I am thinking a simple nodejs script in the server (i.e. initDB.js) that will create an initial user and may be even mock up some projects.

Choose a set of supported browsers

The question here is: which browsers should we support in our sample app? If we could rule-out IE8 we would be in a much better position when it comes to utility functions:
http://kangax.github.com/es5-compat-table/

Today I needed Array.filter and I can see 3 options:

  • use native Array.filter and rule out IE8
  • include underscore.js
  • roll out custom set of helpers

I must say I like the first option the best. The book shouldn't be about IE quirks and it would allow us to write more concise code. WDYT?

grunt watch not working correctly (stops working after the first file modification) on Win 7 x64

For some reason when I run grunt.cmd watch, only the first file modification is picked up correctly and grunt runs its tasks correctly, but any other file modification afterwards is not picked up by the watch task. I'm on Win 7 64 bit (node.js v0.8.14).

I've tried using forceWatchMethod = 'old' but that didn't help.

Any ideas perhaps?

Also, how would I go about LiveReload functionality?

Edit: If I remove 'test:unit' from the default grunt.registerTask it works fine.

Mongolab: reject promise for objects not found

Mongolab chosen to return HTTP 200 and " null " for non-existing item queries: GET collections/{collection}/{_id}. This means that a promise will be fulfilled and a route navigation will take place even if an item is not found.

This is incorrect behavior, we should be preventing route changes (for routes displaying item details / item edits) if a given item doesn't exist.

Testacular (unit) tests got "stuck" from time to time

I'm still having hard-to-track problems with testacular unit test from time to time. This is what I was able to figure out so far:

  • quite often (about 70% of the test runs) testacular gets "stuck" (stops tests execution)
  • to get it "unstuck" I need to open a browser window that is capturing testacular. This makes the rest of the test run and the whole process finishes OK
  • the problem goes away completely if I comment out the 'Normal Responses' tests in the authenticationSpec.js

I'm not sure if the issue is in the test itself or more in testacular but for now I have to comment out this test locally. The funny thing is that I've observed a very similar behavior in the angular-ui project and wasn't able to pinpoint what exactly is happening here. Other people from the angular-ui project reported similar problems.

Wrong message when a new item is saved

Tested in the users admin part. Upon saving a new item we are correctly redirected to a list of items but a confirmation message is wrong (an ID of a newly added item is missing).

Remove the routeCRUD service

The routeCRUD cuts down the LOC no we have to write for a route definition but - at the same time - makes understanding routes very difficult. On top of this we need to have per-route security info and trying to fit it into a general purpose service doesn't fly.

Introduce navigation service

Today the navigation logic is all over the place, in both templates (using ng-href) and controllers (using $location.path()). Let's create a dedicated service ($navigation ?) to abstract and centralize this logic.

Additionally it will allow us to have consistent links for html5 and non-html5 modes.

test file names

I think we should change the naming of tests from filenameSpec.js to filename.spec.js. It makes it cleaner, especially when the filename of the test subject contains hyphens:

file-name.spec.js looks better than file-nameSpec.js

About this app.

Hi Folks!

I'm a beginner JavaScript developer and I'm learning AngularJS as well.

After searching a "framework", "seed-app" or "Angular Bootstrap" (you got the idea) I found your Repo. I've been following your steps for about one week now and I'm learning a lot with you.

So, I hope you forgive me for being a bit impertinent, but can I ask you something about the project?

  • What is its purpose? Is (will) it intent to be used as a "starter"?
  • Are you going to use it to any kind of AngularJs "school class" or tutorial?
  • Is there a "deadline" ou "time frame" to this project be considered finished?
  • I managed to install it, but since I don't have a login and password I can't see the frontend. Would you provide me one? (I'm not willing to use it with a local DB).

=-=-=

Sorry if my comment scares you, but, this is a public repo... =)

I would like to help you somehow if I can. As I said, I'm still learning Javascript (and AngularJS), but I'm enjoying a lot. For now I could help with some HTML/CSS or user testing..

Thanks and congratulations for your good work. I'm learning a lot just by watching your "conversations"...

Add display of the global errors

Re-configure the $exceptionHandler to show how to handle fatal, application-wide errors. We should simply log it and display a nice bootstrap alert. We could show an integration with $http (for example, to store errors suing central logging facility)

Public landing page

Decide what to put on the public (accessible without sign-in) landing page and do the implementation. Functionally speaking it should be a page giving a brief overview of projects and sprints in progress.

This landing page should be:

  • accessible without signing-in
  • read-only
  • used as a landing page when a person is not signed in (so after logout as well)

Login form not shown again when user clicks outside of the modal

Scenario:

  • Open the application
  • Navigate to a route that needs authentication -> login modal is displayed
  • Click outside of the login modal -> login modal is not displayed any more
  • Navigate to another route requiring auth -> login modal is never re-displayed again

I believe that the problem is in the modal directive, in the watch part to be more precise. In the above use case the watch expression always evaluates to true and as a result the watcher function never fires.

Module - Filename convention

@pkozlowski-opensource

By the way, I think we are doing this already but there should be a clear relationship between module names and filenames. If I see that a module I am working on relies upon another module then I want to be able to navigate to that module really quickly to see what is in it rather than having to search around for a file that might have a different name. So to be explicit we should convert file paths to module names by changing forward slashes to hyphens (with the exception that we ignore app or common paths):

Filename <=> Module Name
app/a/b/c.js <=> a-b-c
common/x/y/z.js <=> x-y-z

For example: services.crud => services/crud.js

Is this cool?
Pete

Make clickable items more obvious

I find it counterintuitive that I have to click on an item in a list (for example a project in http://localhost:3000/admin/projects) to edit it when there is no visual indication that I should do this.

I think we should do at least one of a few things:

  • Change mouse pointer to hand when over a clickable item
  • Change the background colour of item when hovering over it
  • Have an edit button/link

Add i18n messageService

Such a service should take a message key and return a localized message corresponding to a key in the current locale. This service should also have additional methods:

  • get a message with some parameters (use interpolate for this)
  • get a message in a specified locale (instead of the current one)

Cannot use arbitrary DB name in Mongolab config.

Currently the dbname ascrum is hard coded into various parts of the application so if you use a different name the system is basically broken - primarily around the mongo-proxy part of the server.

CRUD

It just occurred to me. To make things less magic/hidden, can we somehow wrap all our CRUD stuff up in directive, which users simply pop into their admin page, with some nice transclusion?

Add notification service

Extracted from the issue #39:

@petebacondarwin

Moreover we should have a centralised message notification service, to which we can post messages that will be displayed in a nice way to the user.
Such as "You are now logged in", or "You do not have access to that", or "Unable to save project info."

@pkozlowski-opensource

Yes, this was on my mind for quite some time now. There was an interesting post on the mailing list recently when someone build a flash service. Basically a service that is a key-value store. You can add key->values to this store and those will be available after a route change, then wiped-out on the next route change.

Not sure if I'm making myself clear but basically you would have 2 hashes:

  • current (filled in on the previous route)
  • next - to be exposed after route change

on each successful route change next becomes current and next gets re-initialized to an empty hash.

This automatic wiping-out mechanism assures that the messages get actually cleaned up when not needed any more.

Add directive for the bootstrap's alert

Turn this:

<div class="alert alert-error" ng-show="updateError">
            Update / delete error...
</div>

into:

<alert type="error" show-on="updateError">
            Update / delete error...
<alert>

to show reusable components

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.