Journey into Angular Part Two

This is continuation from my original post Journey Into Angular – Part 1

Clean Up

I wanted to clear up a few things that I did from my previous post. I originally pulled in all of the angular libraries from NuGet. I uninstalled all the angular libraries, and then from within NuGet only installed AngularJS.Core, AngularJS.Resource, and AngularJS.Route

I originally placed all my custom scripts within the script folder, but this was getting mixed in with the scripts being pulled in from NuGet.
A convention that I have seen is that people are creating an app folder and then having all their custom scripts within that folder and subfolders. So I followed that convention and moved all my custom scripts to an app folder, and then updated the_Layout.cshtml view to reference the new location.

Row Click

One of the changes I wanted to make, was that clicking anywhere within a row would toggle the employees state to indicate if they where in or out of the office, instead of just relying on the checkbox. So I created simple method of the office controller


$scope.toggleStatus = function (employee) {
    employee.inOffice = !employee.inOffice;
};

To get it working I just needed to slightly alter the div, and added ng-click=”toggleStatus(employee)


<div class="row" ng-repeat="employee in office" ng-click="toggleStatus(employee)">

Api

Now that I have the application was updating correctly, the next step was to create an api call to update the data on the server.

Currently I was recreating the data with every GET call. As I don’t want / need a database, I moved the data creation out into a static.

I created a new repository class, with the corresponding interface definition


public interface IEmployeeRepository
{
    IEnumerable<Employee> Get();
    void UpdateEmployee(Employee employee);
}

and the actual class


public class EmployeeRepository : IEmployeeRepository
{
    private static readonly ICollection<Employee> Employees = new List<Employee>
        {
            new Employee {Id = 1, ImageUrl = "/Assets/Images/male01.png", Name = "Daniel Craig", InOffice = false},
            new Employee {Id = 2, ImageUrl = "/Assets/Images/male02.png", Name = "Christoph Waltz", InOffice = true},
            new Employee {Id = 3, ImageUrl = "/Assets/Images/female01.png", Name = "Léa Seydoux", InOffice = true},
            new Employee {Id = 4, ImageUrl = "/Assets/Images/male03.png", Name = "Ralph Fiennes", InOffice = true},
            new Employee {Id = 5, ImageUrl = "/Assets/Images/female02.png", Name = "Monica Bellucci", InOffice = true },
            new Employee {Id = 6, ImageUrl = "/Assets/Images/male04.png", Name = "Ben Whishaw", InOffice = true},
            new Employee {Id = 7, ImageUrl = "/Assets/Images/female03.png", Name = "Naomie Harris", InOffice = true}
        };

    public IEnumerable<Employee> Get()
    {
        return Employees;
    }

    public void UpdateEmployee(Employee employee)
    {
        var employeeToUpdate = Employees.FirstOrDefault(c => c.Id == employee.Id);
        if ( employeeToUpdate != null ) employeeToUpdate.InOffice = employee.InOffice;
    }
}

In addition to the Get method, I added a new method on the repository to update the employee information. While passing in the full employee object, I am only updating the single field

With the repository in place, the api needs to be updated to include the repository. I cheated and just created the class on the constructor. In a production system, I would have used a DI container which would have injected in the class, but I didn’t see the need for it with what I am currently doing.

The final change was to put into the POST method to update the employee. The updated controller is


[Route("api/office")]
public class OfficeController : ApiController
{
    private readonly IEmployeeRepository _employeeRepository;

    public OfficeController(IEmployeeRepository employeeRepository)
    {
        _employeeRepository = employeeRepository;
    }

    public OfficeController() : this(new EmployeeRepository())
    {
            
    }

    public IHttpActionResult Get()
    {
        var employees = _employeeRepository.Get();
        return Ok(employees);
    }

    public IHttpActionResult Post(Employee employee)
    {
        _employeeRepository.UpdateEmployee(employee);
        return Ok();
    }
}

To call the REST method from Angular, update the office-repository class to include a new method with using the angular resources: save


officeModule.factory('officeRepository', function ($resource) {
    return {
        get: function () {
            return $resource('/api/office').query();
        },
        save: function(employee) {
            return $resource('/api/office').save(employee);
        }
    }
});

The new method will call the POST method of the API.

Last step is to then update the office-controller to call the save method. The final office-controller class is


officeModule.controller("officeController", function ($scope, officeRepository) {
    $scope.office = officeRepository.get(),
    $scope.toggleStatus = function (employee) {
        employee.inOffice = !employee.inOffice;
        officeRepository.save(employee);
    };
});

With two browsers running, make a change on one browser. Refresh the second browser and the change is displayed correctly.

Still more to be done, as I want to have the second browser updated automatically using SignalR.

As always the code can be found on GitHub.com

Advertisements

My musing about anything and everything

Tagged with: , , , , , , ,
Posted in ajax, Angular, AngularJS, AngularJS-Resource, C#, WebAPI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Enter your email address to follow this blog and receive notifications of new posts by email.

Join 9 other followers

%d bloggers like this: