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

Advertisement
About

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 )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

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

Join 13 other subscribers
%d bloggers like this: