AngularJS - More with ng-repeat

AngularJS is a Javascript MVC framework from the fine folks over at Google. The focus of Angular is building complex HTML based client applications. Its design philosophy is data first, where your data will be updating the DOM. Contrast this to a framework like JQuery where the DOM will update your data.

AngularJS Logo

This is the fourth in a series of posts on AngularJS where we are using Chemistry data from the periodic table to help us understand the framework. The others posts are

  1. AngularJS - Introduction
  2. AngularJS - Introducing AngularJS Controllers
  3. AngularJS - Introducing NG-Repeat
  4. AngularJS - More with NG-Repeat
  5. AngularJS - Image Binding
  6. AngularJS - Introducing Templates
  7. AngularJS - Introducing Routing
  8. AngularJS - Introduction to Services
  9. AngularJS - Introduction to Directives
  10. AngularJS - Further with Directives
  11. AngularJS - Best Practices
  12. AngularJS - CSS Animations

Note: AngularJS does not allow for more than one ng-app directive. When I have multiple angular posts on the home page of my blog, only one application will work. I need to refactor the entire site to account for this. All of that to say this, you are best clicking on a single article so you can see the pages in action.

In this post, we are going to dig a bit deeper into ng-repeat and discover a few things.

To level set, we have a controller called chemistryApp.js. This creates our AngularJS application

chemistryApp.js

var chemistryApp = angular.module('chemistryApp', []);

and a controller that references are json file of chemistry data and sets it to a scope variable

chemistryController.js

chemistryApp.controller('chemCtrl',
    function chemCtrl($scope) {
        $scope.periodic = perioicData;
    }
);

First up, instead of creating an unordered list, we are going to create a table. This is done by putting the ng-repeat directive on a <tr> tag. For example

 <tr data-ng-repeat="element in periodic.elements ">

Then we can add our data on a cell by cell basis. For this example, we are going to link to a Wikipedia article about each element, and then display things like the atomic number, atomic weight, etc. Tying this with our ng-repeat directive and our table markup becomes

<table class="table table-striped table-bordered table-hover table-condensed">
            <tr>
                <th>Name</th><th>Atomic Number</th><th>Weight</th><th>Phase</th><th>Ionization Energy</th><th>Melting Point</th><th>Boiling</th>
            </tr>
            <tr data-ng-repeat="element in periodic.elements ">
                <td><a href="http://en.wikipedia.org/wiki/{{element.name}}" Title="Wikipedia article on {{element.name}}" target="_top">{{element.name}}</a></td>
                <td>{{element.atomicNumber}}</td>
                <td>{{element.atomicWeight}}</td>
                <td>{{element.phase}}</td>
                <td>{{element.ionization}}</td>
                <td>{{element.melting}}</td>
                <td>{{element.boiling}}</td>
            </tr>
        </table>

We now have a list of the Chemical elements in a table.

NameAtomic NumberWeightPhaseIonization EnergyMelting PointBoiling
{{element.name}} {{element.atomicNumber}} {{element.atomicWeight}} {{element.phase}} {{element.ionization}} {{element.melting}} {{element.boiling}}

We can also, just like in our previous example, bind a filter to an input box and search for a chemical element by name and have it filter the list automatically.

   <div id="periodicTable"  data-ng-controller="chemCtrl" >
        <input type="text" data-ng-model="elementNameOnlyTable"/>
        <table class="table table-striped table-bordered table-hover table-condensed">
            <tr>
                <th>Name</th><th>Atomic Number</th><th>Weight</th><th>Phase</th><th>Ionization Energy</th><th>Melting Point</th><th>Boiling</th>
            </tr>
            <tr data-ng-repeat="element in periodic.elements | filter:{name:elementNameOnlyTable}">
                <td><a href="http://en.wikipedia.org/wiki/{{element.name}}" Title="Wikipedia article on {{element.name}}" target="_top">{{element.name}}</a></td>
                <td>{{element.atomicNumber}}</td>
                <td>{{element.atomicWeight}}</td>
                <td>{{element.phase}}</td>
                <td>{{element.ionization}}</td>
                <td>{{element.melting}}</td>
                <td>{{element.boiling}}</td>
            </tr>
        </table>
    </div>
NameAtomic NumberWeightPhaseIonization EnergyMelting PointBoiling
{{element.name}} {{element.atomicNumber}} {{element.atomicWeight}} {{element.phase}} {{element.ionization}} {{element.melting}} {{element.boiling}}

The ng-repeat also has some intrinsic variable definitions. One is $index which is the current key of the element of the loop you are on.

Name$IndexAtomic NumberWeightPhaseIonization EnergyMelting PointBoiling
{{element.name}} {{$index}} {{element.atomicNumber}} {{element.atomicWeight}} {{element.phase}} {{element.ionization}} {{element.melting}} {{element.boiling}}

It is interesting to note that the index is for the values you are filtering on too. So if you were to type Aluminum you will see it becomes the zero element, instead of Hydrogen.

Angular also has directives like ng-hide, ng-show and ng-class along with a plethora of other attributes.

We can use these in conjunctions with $index. This is really the key step along the journey in thinking the "Angular way". You don't want to update the dom via javascript, but use Angular to control what is displayed on your page. As an example of this, let's say we want to hide every other element in the list. We could do something like

 <tr data-ng-repeat="element in periodic.elements" data-ng-hide="$index%2">
NameAtomic NumberWeightPhaseIonization EnergyMelting PointBoiling
{{element.name}} {{element.atomicNumber}} {{element.atomicWeight}} {{element.phase}} {{element.ionization}} {{element.melting}} {{element.boiling}}

We can also perform some Crimes Against web design. For example, nothing is uglier than wrapping your table in Green Bay Packer colors of Green and Gold. So I can add CSS elements like

<style>
        .tableOdd {
            background-color: green;
        }
        .tableEven {
            background-color: gold;
        }
    </style>

Then we can use the ng-class on the <tr> we are binding to in order to make even/odd rows change colors.

<tr data-ng-repeat="element in periodic.elements" data-ng-class="{tableEven: !($index%2), tableOdd: ($index%2)}">

It doesn't look pretty, and there are MUCH better ways to do this, but it gives you an example of how to think the "Angular way"

NameAtomic NumberWeightPhaseIonization EnergyMelting PointBoiling
{{element.name}} {{element.atomicNumber}} {{element.atomicWeight}} {{element.phase}} {{element.ionization}} {{element.melting}} {{element.boiling}}

Last, we can also do fun things like sort by using select lists to quickly filter data. For example, we create a dropdown list for both the element phase

 <select data-ng-model="elementPhase">
            <option value="">All</option>
            <option value="Gas">Gas</option>
            <option value="Solid">Solid</option>
            <option value="Liquid">Liquid</option>
            <option value="Synthetic">Synthetic</option>
        </select>

and an ordering criteria

<select data-ng-model="elementOrder">
            <option value="name" selected>Name (ascending)</option>
            <option value="-name">Name (descending)</option>
            <option value="melting">Melting Point (asc)</option>
            <option value="-melting">Melting Point (desc)</option>
        </select>

We can then use the ng-filter and ng-order directives to filter and sort our table. Further, we can combine with our text box for searching by name and chain them together.

 <tr data-ng-repeat="element in periodic.elements | filter:{name:elementName} | filter:{phase:elementPhase} | orderBy:elementOrder">

Ultimately, our HTML looks like

<div id="periodicTable5"  data-ng-controller="chemCtrl" >
        Element Name:<input type="text" data-ng-model="elementName"/>
        &nbsp;State:
        <select data-ng-model="elementPhase">
            <option value="">All</option>
            <option value="Gas">Gas</option>
            <option value="Solid">Solid</option>
            <option value="Liquid">Liquid</option>
            <option value="Synthetic">Synthetic</option>
        </select>
        &nbsp;Order:
        <select data-ng-model="elementOrder">
            <option value="name" selected>Name (ascending)</option>
            <option value="-name">Name (descending)</option>
            <option value="melting">Melting Point (asc)</option>
            <option value="-melting">Melting Point (desc)</option>
        </select>

        <table class="table ">
            <tr>
                <th>Name</th><th>Atomic Number</th><th>Weight</th><th>Phase</th><th>Ionization Energy</th><th>Melting Point</th><th>Boiling</th>
            </tr>
            <tr data-ng-repeat="element in periodic.elements | filter:{name:elementName} | filter:{phase:elementPhase} | orderBy:elementOrder">
            <td><a href="http://en.wikipedia.org/wiki/{{element.name}}" Title="Wikipedia article on {{element.name}}" target="_top">{{element.name}}</a></td>
                <td>{{element.atomicNumber}}</td>
                <td >{{element.atomicWeight}}</td>
                <td>{{element.phase}}</td>
                <td>{{element.ionization}}</td>
                <td>{{element.melting}}</td>
                <td>{{element.boiling}}</td>
            </tr>
        </table>
    </div>
Element Name:  State:  Order:
NameAtomic NumberWeightPhaseIonization EnergyMelting PointBoiling
{{element.name}} {{element.atomicNumber}} {{element.atomicWeight}} {{element.phase}} {{element.ionization}} {{element.melting}} {{element.boiling}}

The interesting thing to note about this too is that this page is pretty heavy. It has many tables with the Periodic elements. However, by using client side code, we download all of the elements only once when we get our JavaScript file. The client side functionality does the page building, helping the page load quicker.

For those of you who have been web coding for a while, these few number of lines to have all of this client side functionality is magic. Seriously, magic.

You can either visit http://angularperiodic.azurewebsites.net/ to see the code in action and as always find the code out on GitHub


 

GitHub Repository Not Found - Case Issue?

This morning, I was pushing a small update to my blog and I received an error that my GitHub repository was unable to sync. Usually my workflow goes something like this...

  1. Commit GitHub changes via WebStorm
  2. If that doesn't work, use the GitHub Windows/WPF client http://windows.github.com/
  3. Use command line Git

While I want to get better at 3, 1 is much easier and when I do 2, I am in a hurry. :)

Ultimately, I am not really sure what happened. My development environment worked fine yesterday when I committed changes, but today there were issues. I THINK it may have to do with case differences between when I setup the repository locally and how GitHub may be handling it on the backend today.

When I pushed my commit to the repo with the command

git push origin master

The following error was returned

remote: Repository not found.
fatal: repository 'http://github.com/jptacek/JPTACEK.com.git/' not found

You can see the message below

GitHub Error

Again, no changes have been made to the repo. Similar messages appeared in the GitHub client and WebStorm. Other repositories I had on GitHub I was able to commit and push changes to. The only thing I could think was that the case was different on my local origin in comparison to the backend GitHub repository.

The fix was simple enough, reset the origin with and change the case of the URL so that it was exactly the same as my repository on GitHub.

 git remote set-url origin https://github.com/jptacek/JPtacek.com.git

After this, I was then able to commit changes without issue in all the different client apps as well as the command line.

as shown in the following screen shot

Repo found

It strikes me as pretty odd that GitHub would suddenly stop working because of a case issue between my local dev machine, which has been working fine for many months, and the GitHub server. However, that appears to be the case in this instance.

Pretty much just documenting this for my future self :)


 

What is Yammer... and why should your company use it?

In real life, I can tend to be a socially awkward computer geek. In digital life, I am quite social where I have accounts on Twitter, LinkedIn, Google+, etc. Recently, our company has started using Yammer and I struggled with do I need another social media account. How does Yammer work better than the sites I already use? How does it supplant and/or supplement the awesome way Skyline uses SharePoint to drive collaboration within our growing company?

One of my favorite words to use is Grok. It is from Robert Heinlein’s Stranger in a Strange Land. Essentially, grok is to understand something truly (http://en.wikipedia.org/wiki/Grok). I try on occasion to grok things. It doesn’t always work well. So, here is where I am currently on trying to grok Yammer and how it can be used in SharePoint, within our teams, and Skyline (or your company) to enable us to better deliver for our clients.

So what is the first thing I think….. Yammer is ALL about the timeline. What do I mean by that? Let me start by example. I walk around with what I call my little black book, which is a Moleskine I use for writing stuff in it all the time. It is meeting notes, To-Dos, etc. I used to use OneNote a lot, but the reason I moved away from it is there is no sense of the flow of time. I know if I wrote something ~ three months ago, but I don’t know if I wrote it in a SharePoint ideas folder, a blog ideas folder, or my dev things to explore. I was impacted because I never had a good way to see things chronologically by paging through the content flow. The lack of timeline has moved me away from OneNote unless it is recording info from my brain. I use it for information I need at a later point. For example, what are my favorite recipes, what is the URL that explains WIF security, what is the wireless password, what music do I need to check out, that kind of stuff. OneNote has become the persistence mechanism for information I need.

I see SharePoint as the location of storage for information for companies. Essentially where instead of looking for information that is pertinent to me, SharePoint is information that is important to an organization. It is there for persistence of business information. What is the customer deliverable for a project, where is information about our benefits, where is the blog post one of my colleagues wrote on FAST search. However, not all business information NEEDS to be persisted. Some of it can be very valuable in the timeline sense. I posted a link recently within our internal Skyline Yammer about Mercury Marine expanding in Fon Du Lac. Is it interesting to Skyline? Maybe. Does it need to be in SharePoint for business needs? No. Is the information valuable for a short time frame? Definitely. It is that ephemeral type of content and discussion that Yammer is useful for.

So here is an EXCELLENT example of where Yammer is useful for an organization and how the concept of a timeline is valuable. Our CEO, Mitch Weckop, writes some pretty interesting blog posts on our SharePoint Intranet. Mitch talks about the economy or current legislation and how it can impact our business. Mitch meets with lots of our customers and shares his experiences in terms of how we can make Skyline better. Using these posts, Mitch does a great job trying to engage our associates in dialog. However, unless you subscribe to the blog posts via an alert or you notice it on our Skyline Intranet, our associates would miss it. However, if you log onto Yammer, where Mitch also posts a link back to his blog, it appears in our Associates’ timeline, right near the top, since it is recent. Organizationally, this timeline drives further value because unless you are Mitch, you are not seeing any comments that are being put on his blog after you visit it. When our company has a dialog within Yammer about the blog posts, everyone will see recent comments because they are at the top of the timeline. It essentially pokes the discussion back to the top of the information flow. Previously, this would not happen unless you were constantly checking the blog posts internally, because SharePoint does not have a great, “hey look here!” mechanism.

Yammer Home Page

So ultimately, thing one I have come to understand about Yammer is the value comes in taking the flow of organizational information, and getting in front of people in terms of timeliness. THIS is the reason email continues to persist I believe. You have a timeline. You know the emails of today are MUCH more important than the information of six months ago. SharePoint as the persistence of business critical information has a difficult time projecting this information as a flow of time for its users. Hence, Microsoft’s buy of Yammer. It allows Microsoft to provide time pertinent information to organizations on top of SharePoint’s persistence based excellence.

Thing two about Yammer is the social aspect. Any of you folks who jump on Twitter realize you learn and understand people a bit better than you otherwise would. If you follow me on Twitter, you know I occasionally babble on my family, listen to too much music, etc. Is there any business value in that? You bet. As organizations grow, they are not going to have a metaphorical water cooler to gather at. Companies need to try and use a social tools like Yammer to get a sense of the people they work with. At Skyline recently we have learned through Yammer that some of our Green Bay associates were rocking some pretty awesome mustaches for Movember. We learned about the results of sponsorships we do for hackathons in Milwaukee. We also learned who is on the naughty list (Bear fans) and who is on the nice list (Packer fans), or vice versa. Using Yammer helps employees build social capital with your organization. The cool thing this social capital does is allow us to have bad days (I went to school at UW-Madison, so I apologize if this is getting too touch/feely). You are much more likely to give the benefit of the doubt to a peer when they have a bad day if you know them personally, and social tools like Yammer help build that for organizations, especially geographically disperse organization where you do not have day to day interactions. Digital tools will never be the most important part of building social capital, but it can be valuable part, because even though you may not interact on a day to day basis, you still can learn about your peers. With Yammer, you can help socialize your culture.

To summarize

1 – Yammer is timeline. Get timely information in front of associates and yourself

2 – Yammer is dialog. Dialoging about the timely information to provide input, feedback and discussion

3 – Yammer is NOT about persistence. Yammer is not the place for project proposals, financials, etc

4- Yammer is people. Yammer can be the virtual water cooler (or Skyline style, virtual coffee machine). An opportunity to engage people as people, rather than employees

5 – Yammer is NOT required. Just like you don’t want to try and keep up to date on your entire Twitter feed, you shouldn’t have to feel like that with Yammer. Business persisted information happens generally outside of Yammer, business supplementing happens with in. As cultures grow, this can change over time, but definitely not day one!

If you want to learn more about Yammer or how your organization can use, feel free to reach out to me!

This blog origanally appeared at http://www.skylinetechnologies.com/Blog/Article/2428/What-is-Yammer-and-why-should-your-company-use-it.aspx#


 

John Ptacek I'm John Ptacek, a software developer for Skyline Technologies. This blog is my contains my content and opinionss, which are not those of my employer.

Currently, I am reading The Dark Forest by Cixin Liu (刘慈欣)

@jptacekGitHubLinkedInStack Overflow