Tuesday, October 20, 2015

DB Designs for Music School Online (relational and nosql)

So, I considered two different DB designs for my application.  One is a relational database schema, and the other is a non-relational (noSql) database schema.  Relational databases are like (Oracle, and mySQL), and noSQL is like (MongoDB).

Here is my relational database design ER Diagram.  The arrows point from FK (foreign key) dependencies.  As you can see its a pretty simple database.  Everything is centered around User.


Now I also made a ER Diagram for my noSQL database.  The brackets indicates which attributes hold documents. In cases where the documents will be other documents - that document's structure is outlined.


As you can see there is a vast difference between these two database styles.  The first design , the relational database has multiple tables that are connected by foreign keys.  In the second design we have a schema-less design.  

Personally I prefer the schema-less design because, I think it is easier to maintain.  Also Music School Online is a study on development on the MEAN stack, MEAN means you are using a MongoDB, ExpressJS, AngularJS, NodeJS full-stack framework.  For more info see wikipedia.

But instead of using MongoDB, I am actually going to use AWS's version of MongoDB which is called DynmoDB. The reason being I really like AWS (Amazon Web Services).  They are the best cloud based web services out there.  Plus I can host a small noSQL database there for free or for something like $0.30 a month...yes that is right, 30 cents a month.

Here's a video about Dynamo DB.

October 21, 2015
I ran into some problems with the DynamoDb approach. The only way I could find to use it with my AngularJS application would be to use Amazon's Identity Access Management (IAM) services which requires the user to sign-in using Facebook, Google, or another 3rd party authentication provider. I do not want to require users to login using a third-party authentication so I am going to use the traditional MEAN stack way instead. This involves using MongoDB with Mongoose. More info on this to come.

October 23, 2015
Actually, I couldn't figure out how to get mongodb installed locally on Ubuntu 15 (which is what OS I'm using on my dev machine).  So I signed up for a free managed hosting service at https://mongolab.com. It turns out they are running a mongo db in AWS...(I didn't know you could do that!)

Monday, October 19, 2015

Making a page with a video background in HTML5

I know you have seen lots of new pages popping up all over the internet that have flashy looking videos as their backgrounds.  Surprisingly, it generally looks very good. So I am going to create a page that will be used as the homepage/landing page for a website, that will have a space for a video background.

Ok, this was pretty simple. All I had to do was include the following HTML in my index page.
<div class="header-unit">
<div id="video-container">
<video autoplay loop class="fillWidth">
<source src="http://vjs.zencdn.net/v/oceans.mp4" type="video/mp4"/>
Your browser does not support the video tag. I suggest you upgrade your browser.
</video>
</div><!-- end video-container -->
</div><!-- end .header-unit -->

With the following css:
.header-unit {
    height: 100%;
    position: relative;
    overflow: hidden;
}

#video-container {
top:0%;
left:0%;
height:100%;
width:100%;
overflow: hidden;
}
video {
    position:absolute;
    min-width: 100%;
    min-height: 100%;
    z-index:-10;

}

This created the video background and formatted it to zoom in to fit the page.

Done!

Making a page nav directive in Angular JS

In this post I will be explaining how I created a page nav directive in AngularJS.  The page nav is a navigation header on the webpage.  Here is what facebook's top nav looks like:
Its just going to be that top bar that shows up at the top of every page..

Angular JS has a nifty feature called 'directives'.  This is where you can specify your own custom HTML tag.  The tag could be anything...a header nav for example.  Then in your pages you can simply use this directive to display your nav.

So How do we go about creating this directive for this nav?  

Here we go:

First, I am going to create a project file structure to keep my project organized.  This is the one I am using:

app
   assets
        javascript
            controllers
            directives
            filters
            services
            vendor
        styles
        templates
            directives
    css
    images
    views
node_modules
server
    models
    routes

Don't ask me why there is a css and a styles folder...both of these store css files. 

So...the first thing I am going to do is create a new file in the directives folder called nwPageNav.js
This file is going to create the directive.

angular.module("MusicSchool").directive('nwPageNav', function(){
  return {
    replace: true,
    restrict: "E",
    templateUrl: "assets/templates/directives/nwPageNav.html",
    controller: function($scope, $location){
      $scope.isPage = function(name){
        return new RegExp("/" + name + "($|/)").test($location.path());
      };
    }
  };
});

The 'replace: true' specifies not to include the actual directive tag in the DOM when the directive is used. 
i.e.
<div>Stuff you put in directive</div> 
NOT 
<div><yourdirective>Stuff you put in directive</yourdirective></div>  

Why somebody would want 'replace:false' is beyond me. If I ever come across a situation where this is desired I will be sure to let everyone know.

The 'restrict: "E"' means the directive is only going to be used as an element and not an attribute.
i.e.
<likethis></likethis>    not     <div likethis></div>


Now in the templates/directives folder I am going to put the html for this directive:
<ul class="nav navbar-nav">
  <li ng-class="{'active': isPage('locker')}"><a href="#/locker">Locker</a></li>
  <li ng-class="{'active': isPage('classroom')}"><a href="#/classroom">Classroom</a></li>
  <li ng-class="{'active': isPage('community')}"><a href="#/community">Community Board</a></li>
</ul>

You'll notice that there is a isPage function being called on each link in the nav. This function was specified in my directives controller:
    controller: function($scope, $location){
      $scope.isPage = function(name){
        return new RegExp("/" + name + "($|/)").test($location.path());
      };
    }
It simply checks to see what page we are one and then highlights the nav link accordingly.

If you are on the locker page for example, that nav link will look different from the others...this is just a nice touch in my opinion.  It is using the ng-class directive, a built in angular directive which binds to the expression 'isPage(pagename)' which will be true or false depending on if you are on that page, and sets the class of the link to 'active'.  

If you don't know what data-binding is...you should really find out.  Its one of the greatest things I've ever seen so far in web development, and its something that only Angular does.  It allows variables to update instantaneously across the application, which will affect how the app looks.  The variables can be modified in the controllers and are automatically updated in the views.  This is called one-way data binding.  If you use models in your views (like for a form field entry for example) you can do two-way data binding. This is when an user input value is bound and can update the app instantaneously.  However don't get confused...this only works with ng-model bound variables...you cant just change something in the DOM of your view (like with jQuery) an expect it to data bind.

Now in my index.html (the main app page) I am going to put:
    <nav>
      <div class="container-fluid">
        <div class="navbar-header">
          <div class="navbar-brand">
            <a href="/#/">Music School Online</a>
          </div>
        </div>
        <nw-page-nav></nw-page-nav>
      </div>
    </nav>

The 'nw-page-nv' tag is the directive I just created, this is what is outputting my nav. The 'nav' tag is a HTML5 element which allows you to group together nav links, this will help screenreaders.  Its a new HTML5 thing, it doesnt do anything in particular except let everyone know where your navs are.  The css classes 'container-fluid', 'navbar-header', and 'navbar-brand' are simply css styles that I am using for my nav.  These are from the bootstrap.css.  You can get bootstrap from http://getbootstrap.com/css/ These are some common css properties that can really help with styling web development..in this case it makes my header nav responsive.  For example, this is what it looks like full screen:
And here is what it will look like on a small screen (a phone):
This responsiveness is a great feature.


Ok so that is it for the nav bar...stay tuned for the next episode.





Sunday, October 11, 2015

One Line, One Thing

"When one line of code only does ONE thing, it makes code easier to understand..." -quote by someone who codes.

My reaction: I think making one line of code do as many things as it can is better.  But the person who said the above quote has a point...from now on I will start doing this (making each line do just one thing) especially if its code I know others will read. (No point in making people mad)

Saturday, October 10, 2015

Did you know you could do this?:
var time = +new Date();
in Node JS...the + converts the time to milliseconds.

using nodejs and angular at the same time (a hybrid single page app)?

I am new to Angular JS...and the single page web app idea. I am used to web forms that post data to a back-end server where the server can process it as needed (Oauth, db calls, etc). But in Angular it seems like the only way to do this is to use the $http service. Is this correct? This seems to be OK to me because instead of using server side pages you can set up your own API and then use Angular $http to handle things. However, it just seems like there might still be some benefits to using Angular for your web app but also making other parts of your app use a normal back-end setup (like Node JS)...is it considered bad practice to have half of the app's urls use Angular and the other half directly using Node JS. I am not sure if this is possible but I would imagine it is. My guess is all you need to do for this is to set your routes a certain way. What thoughts do people have on this?

October 21, 2015
I just discovered that the essence of this question is what the MEAN stack is all about. The mean stack uses ExpressJS to create the backend api that is used by the frontend AngularJS. For a good book about MEAN stack...to learn it, check out MEAN Web Development