RMD (Rapid Mobile Development) with Telerik AppBuilder

As a developer coming from a web development background with a partner who’s asking for an immediate mobile application, my best choice was Telerik’s AppBuilder. There are 2 types of mobile app that you can build with AppBuilder. First is a Hybrid Mobile App and second is Native with Nativescript.

My Experience

Building a Hybrid mobile app with AppBuilder is pretty straightforward, specially if you have Visual Studio 2015 installed on your machine. You just need to install a extension for  Visual Studio and your ready. There is a separate IDE but it comes with a price. And since I am on Visual Studio IDE for a very long time, I opted in installing the extension.

After installing the extension, I can now run my code via a built-in simulator.

AppBuilder.png

It just took me a month to complete a full LOB Hybrid Mobile app with AppBuilder. Now we nudged the bar  up and move to native development this time with NativeScript.

The second app that we developed was for a university in california and we want a native look and feel. Our choice? Nativescript with AppBuilder. The language we use? Javascript. For the UI? XML. And how long did we create the app? 1 Month.

Why go native with Nativescript? Its much faster than the Hybrid of course and here are the good parts:

  1. It supports Javascript and Typescript
  2. You can apply the same styling as you would on Hybrid and Web apps.
  3. Wide array of plugins such as camera, calendar, barcode scanner, etc.
  4.  Active community.
  5. End to End development with AppBuilder. I was able to develop the native app without a mac. Just iTunes for deploying the package on my phone.

I will write a blog later on on how you can build hybrid and native apps with the AppBuilder.

For now, I just want to entice you with the good things that AppBuilder can bring on to your mobile development project.

Right now we are on our third project and we still use Telerik AppBuilder.

 

Advertisements

Interprocess Communication via Self Hosted WCF

Lately I was asked if there is a way to allow 2 apps to communicate even if they are belonging to 2 different exe’s . Fortunately for me I have the source code of both 2 apps. The main reason why instead of merging the projects, we went to IPC or interprocess communication is because, I belong to a team that maintains the other windows forms app and the other project or exe belongs to another team that has their own deliverables. And another thing is, we want to deploy the IPC functionality the soonest. It means it is badly needed.

The way to do it is have a listener in the second app and let the first app talk to the second app with the same url.

Oh, first lets create something (object) that can be shared between the 2 apps. When you communicate, you transfer knowledge, words, etc. In our case lets transfer some data to the other app.

The Data

[DataContract]
[Serializable()]
public class UserInformation
{
[DataMember]
public string Name { get; set; }

[DataMember]
public DateTime BirthDate { get; set; }

[DataMember]
public string Address { get; set; }
}

The Service Contract

This will be self hosting service which will be hosted in the listener app.

[ServiceContract(Namespace = “https://www.francorobles.com”)]
public interface IUserServiceContract
{
[OperationContract]
int UpdateUserInformation(UserInformation userInformation);

}

The Service Implementation

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class UserService : IUserServiceContract
{
public int UpdateUserInformation(UserInformation userInformation)
{
return 1;
}
}

Starting the listener

This code block will be in the listener app. What it does is we instantiated a wcf service inside our windows app via named pipe.

Dim address As String = String.Concat(“net.pipe://localhost/user/userservice”, Environment.UserName)
Dim _userService As UserService = New UserService()
Dim serviceHost As New ServiceHost(_userService e)
Dim binding As New NetNamedPipeBinding(NetNamedPipeSecurityMode.None)
serviceHost.AddServiceEndpoint(GetType(IUserServiceContract), binding, address)
serviceHost.Open()

Calling the listener

Here we called the listener via the same url that was instantiated in the listener app. Then we created a UserInformation object and passed it like we do in a normal wcf service.

Dim address As String = String.Concat(“net.pipe://localhost/user/userservice”, Environment.UserName)
Dim binding As New NetNamedPipeBinding(NetNamedPipeSecurityMode.None)
Dim ep As New EndpointAddress(address)
Dim channel As IUserServiceContract = ChannelFactory(Of IUserServiceContract).CreateChannel(binding, ep)

Dim _userInformation as new UserInformation()
_userInformation.Name = “Franco Robles”
_userInformation.BirthDate = DateTime.Parse(“1985-10-08”)
_userInformation.Address = “Makati, Philippines”
channel.UpdateInformation(_userInformation)

 

And thats pretty much about it. There are many types of IPC (Inter Process Communication), WCF via named pipe just suits my needs. Maybe you encounter the same scenario sooner or later and hopefully this post will be a starting point for you.

Happy Coding!!!

 

 

 

 

 

Restoring NuGet Package

There are plenty of ways to restore missing nuget packages. In many cases you might just want to copy packages from one project to another. The easiest way to copy packages from 1 project to another is by using the below command:

Update-Package -Reinstall -ProjectName <ProjectName>

where <ProjectName> is the name of your project.

Second, if you want to restore packages in the entire solution is, you have to omit -ProjectName in the above command like so:

Update-Package -Reinstall

And that’s it, as simple as that. I have encountered this many times already and I have to take note of the command by making a post about it. Through this I can just simply look into my blog and wallaaaahhh, there it is.

 

Real Time Web with SignalR and ASP.NET MVC

This afternoon I was thinking about an app where users will be notified in real time. Some suggestions were raised but at the moment I think only Node.JS and SignalR are the most viable candidate for this scenario. For this post, since I am going to use ASP.NET MVC, I will use SignalR which is native to .NET.

Okay, for those who are not familiar yet with SignalR. According to its site, it is a new library for ASP.NET developers that makes it incredibly simple to add real-time web functionality to your applications. For me, basically, it is the most convenient way in notifying the client that something happened from the server in real time. No need for work around or any sort.

Now, time for the development.

1. First we need to get a reference of SignalR from Nuget. You can also get it from Github. Or download it as zip and add it as reference. But if you are new, I would suggest using nuget.

– Install-Package Microsoft.AspNet.SignalR

SignalR_Nuget

2. Once you have it installed. Let’s create  a Hub. A SignalR Hub enables you to make remote procedure calls (RPCs) from a server to connected clients and from clients to the server.

– First we need to add a folder to our web project called Hubs.

– Then create a class called CustomerHub. Below is how it should look like. I intentionally made it empty since it just acts like a fake hub. All the crud operation happens in the actionresult and you will find out how i called the client method from the actionresult once you finished reading this post.

using Microsoft.AspNet.SignalR;

namespace CustomerSite.Hubs
{
    public class CustomerHub : Hub
    {
        
    }
}

– Then another important part is to add the startup class which does all the mapping.

using Owin;
using Microsoft.Owin;
[assembly: OwinStartup(typeof(CustomerSite.Hubs.Startup))]
namespace CustomerSite.Hubs
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            // Any connection or hub wire up and configuration should go here
            app.MapSignalR();
        }
    }
}

3. Now lets get back to our view.

– Add a reference to SignalRJS.

<script src=”~/Scripts/jquery.signalR-2.1.2.js”></script>

– Set a reference to the available hubs that we created, in this case the CustomerHub that we created as shown below.

<script src=”/signalr/hubs”></script>

– This is how my Layout looks like.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Realtime Web with SignalR</title>
    <link href="~/Content/Site.css" rel="stylesheet" type="text/css" />
    <link href="~/Content/bootstrap.min.css" rel="stylesheet" type="text/css" />
    <script src="~/Scripts/modernizr-2.6.2.js"></script>
    @RenderSection("styles", false)
</head>
<body>
    <div class="container body-content">
        @RenderBody()
    </div>

    <script src="~/Scripts/jquery-1.10.2.min.js"></script>
    <script src="~/Scripts/bootstrap.min.js"></script>
    <script src="~/Scripts/knockout.js"></script>
    <script src="~/Scripts/jquery.signalR-2.1.2.js"></script>
    <script src="/signalr/hubs"></script>
    @RenderSection("scripts", false)
</body>
</html>

4. The client side SignalR registration with knockout.
-> self.hub = $.connection.customerHub; //tells the hub object to point to customerhub on the server.
-> self.hub.client.getCustomers = function () { //is a method that will be called from the server.
self.loadCustomers();
}
-> $.connection.hub.start(); // the client side listener

function AppViewModel() {
    var self = this;

    self.hub = $.connection.customerHub;

    self.hub.client.getCustomers = function () {
        self.loadCustomers();
    }

    $.connection.hub.start();
    
    ... //Code removed here just for this post.

    //A function for loading the customer view via ajax.
    self.loadCustomers = function () {
        $.ajax({
            url: '/Home/CustomerList',
            success: function (data) {
                $("#customerlist").html(data);
            }
        });
    };

    //The function for updating and adding a customer.
    self.submitForm = function () {
        var url = '/Home/SaveCustomer';
        if (self.isEdit()) {
            url = '/Home/UpdateCustomer';
        } 
        $.ajax({
            url: url,
            data: {
                firstName: self.firstName(),
                lastName: self.lastName(),
                address: self.address(),
                phone: self.phone(),
                creditLimit: self.creditLimit(),
                customerSince: self.customerSince(),
                id: self.customerId()
            },
            success: function (data) {
                if (String(data.saved) == 'true') {
                    self.formVisible(false);
                    //self.loadCustomers();
                }
            }
        });
    };
}
ko.applyBindings(new AppViewModel());

5. For the server side to client interaction via ActionResult.

public ActionResult SaveCustomer([Bind(Exclude = "Id")]CustomerViewModel customer)
        {
            provider = new CustomerProvider();
            bool saved = provider.AddCustomer(customer);
            IHubContext hubContext = GlobalHost.ConnectionManager.GetHubContext();
            hubContext.Clients.All.getCustomers();
            return Json(new { saved = saved }, JsonRequestBehavior.AllowGet);
        }

The most important part here are these 2 lines. Basically, what this does is it gets the CustomerHub context and call the getCustomers method that we declared on the client.

IHubContext hubContext = GlobalHost.ConnectionManager.GetHubContext<CustomerHub>();
hubContext.Clients.All.getCustomers();

This is the screen capture of the app running side by side updating each other. We’re done.

AppRunning

By the way, I will post a followup blog on DependencyInjection with SignalR.

Dependency Injection with StructureMap and ASP.NET MVC

According to this article, DI or Dependency Injection is a software design pattern, a particular case of the Inversion of Control pattern, in which one or more dependencies are injected into dependent objects. The pattern is used to create program designs that are loosely coupled and testable.

For me, what matters is the last 2 terms “loosely coupled” and “testable”. But with the number of DI tools out there which would you choose? Well, this article has the best comparison so far. And I have decided to use structuremap because its actively maintained, plenty of new features which I am going to explore later on on the next blog.  But overall? Structuremap is highly configurable.

So, let’s start.

1. Get structuremap via nuget.

nuget

 

 

2. For this article lets resolved the dependencies in our Global.asax file.

– In the below snippet on Application_Start method, Structuremap basically has an ObjectFactory class that let’s you configure your dependency resolutions. On the below snippet, I am telling structuremap to grab the concrete class CustomerProvider for my ICustomerProvider interface.

ObjectFactory.Initialize(x =>
{
     x.For<ICustomerProvider>().Use<CustomerProvider>();
});

 

3. Now time for the real use of DI.
– In the below snippet is what is called Constructor Injection. There is another way too called Property Injection. Basically, what it does is to simply remove the concrete class from being assigned to ICustomerProvider. So that later on, I can modify the concrete class’s implementation without modifying my controller.

public class HomeController : Controller
{
        ICustomerProvider provider;

        public HomeController(ICustomerProvider provider) {
            this.provider = provider;
        }

        public ActionResult CustomerList()
        {
            return PartialView(provider.GetCustomers());
        }
}

 

4. If we run the program and we encounter a parameterless constructor issue. The solution to that is override the defaultcontrollerfactory and let Structuremap instantiate the controllers.

public class StructureMapControllerFactory : DefaultControllerFactory
    {
        protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
        {
            if (controllerType == null)
                return base.GetControllerInstance(requestContext, controllerType);

            return ObjectFactory.GetInstance(controllerType) as Controller;
        }
    }

– Then we modify our initialization to this.

ObjectFactory.Initialize(x =>
{
     x.For<ICustomerProvider>().Use<CustomerProvider>();
});
ControllerBuilder.Current.SetControllerFactory(new StructureMapControllerFactory());

On the next blog, I will cover a deeper topic on this.

Python Development with Eclipse and PyDev

This afternoon I was approached by a junior developer and asked me how I started my python apprenticeship. I told him take a look at my blog tonight I’ll show you the steps.

The Steps

1. Grab Eclipse from eclipse.org. By the time of this writing, I am using Luna.

2. Grab python from python.org. I am using 2.7.8 during this post.

3. Install additional software on eclipse.

– Go to Help > Install New Software. And on the work with field, add http://pydev.org/nightly. Why nightly? Because it is the nightly build and the nightly build contains the recent updates.

Installing_PyDev_on_Eclipse

– When asked if do you trust the certificate? Just check the box because you have no other choice anyway. =)

– Now we are all set. Let’s create a simple loop which prints out the content of a list.

theList = [1,1,2,3,5,8,13,21]

def firstLoop(theList):
    for item in theList:
        print item
    
firstLoop(theList)

 

4. Let’s run our first program and it should print out the content of the list as expected.

SampleProgram

 

So, your first program is running. Are you going to stop from here? I won’t.

If you disagree with what I posted, feel free to hit me up in a form of an email. Please visit my site www.francorobles.com if you need to know more about me. I will be blogging every night to share what I know.

 

Code Coverage with Chutzpah

There was a question in stackoverflow on how to do code coverage in JS with Chutzpah. This is just a short blog on how I did it.

1. First download Chutzpah from codeplex.

Chutzpah

 

2. Now extract it and do the following.

– I extracted chutzpah in the below path.

ChutzpahLocation

– And the location of my js files is here.

UnitTestsLocation

– So, below is how I do code coverage using the chutzpah’s console.

doing_the_console

– And yes of course the result.

resultOfChutzpahCodeCoverage

Nice isn’t it!!!

I will be bloggin everyday from .net,java,python,LAMP,MEAN and all other important topics. This is my way of challenging my self and not become stagnant with just 1 programming/scripting language.

Please also check my site www.francorobles.com if you want to know more about me.

 

CRUD with KnockoutJS, ASP.NET MVC and NHibernate

A friend of mine asked me to teach him a simple CRUD with KnockoutJS using NHibernate because he is already used to EntityFramework. Well, I told him to buy me a grande coffee first at starbucks, and he did. So in order for him and for the others to get to see it in action here is how its done.

First of all, for those of you who doesn’t know what is NHibernate, it is an Or Mapper like EntityFramework. Here is a comparison just in case you might want to know the difference between the 2.

Best comparison so far.

http://www.devbridge.com/articles/entity-framework-6-vs-nhibernate-4/

Now let’s work.

1. First, let’s download the latest release of NHibernate from Nuget.

NHibernate

3. Now since we want xml less mapping, lets get Fluentnhibernate from nuget. During this post, the latest stable version is 1.4.0.

– From your Package Manager Console. type the following “Install-Package FluentNHibernate -Version 1.4.0”

4. After successfully installing FluentNHibernate, your datastore library should now look like below.

FluentNhibernate

5. Now let’s set up a helper for NHibernate which will allow us to connect to the database.
– Okay, basically what the below does is create a SessionFactory.
– Connect to a local data soure from my App_Data directory.

public class CustomerContext
    {
        private static ISessionFactory sessionFactory;
        private static ISession session;
        private static ISessionFactory SessionFactory {
            get {
                if (sessionFactory == null)
                    SetSessionFactory();

                return sessionFactory;
            }
        }
        private static void SetSessionFactory() {
            sessionFactory = Fluently.Configure().Database(MsSqlConfiguration.MsSql2012.ConnectionString(@"data source=(LocalDB)\v11.0;attachdbfilename=|DataDirectory|Customers.mdf;integrated security=true;"))
                .Mappings(m => m.FluentMappings.AddFromAssemblyOf()<Customer>())
                .ExposeConfiguration(c => new SchemaExport(c))
                .BuildSessionFactory();
        }

        public static ISession OpenSession() {
            return SessionFactory.OpenSession();
        }
    }

6. Let’s create a mapping to our Customers table in the database to our Customer entity.

public class CustomerMap : ClassMap<Customer>
    {
        public CustomerMap()
        {
            Id(c => c.Id);
            Map(c => c.FirstName);
            Map(c => c.LastName);
            Map(c => c.Address);
            Map(c => c.Phone);
            Map(c => c.CreditLimit);
            Map(c => c.CustomerSince);
            Table("dbo.Customers");
        }
    }

7.  Now, below is self explanatory, I created the CRUD methods which inherited from an Interface.

public class CustomerViewModel : ICustomerProvider
    {
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Address { get; set; }
        public string Phone { get; set; }
        public decimal CreditLimit { get; set; }
        public DateTime CustomerSince { get; set; }

        #region NHibernate
        public List<CustomerViewModel> GetCustomers()
        {
            using (var context = CustomerContext.OpenSession())
            {
                return context.Query<Customer>().Select(c => new CustomerViewModel()
                {
                    Id = c.Id,
                    FirstName = c.FirstName,
                    LastName = c.LastName,
                    Address = c.Address,
                    Phone = c.Phone,
                    CreditLimit = c.CreditLimit,
                    CustomerSince = c.CustomerSince
                }).ToList();
            }
        }

        public bool AddCustomer(CustomerViewModel customer)
        {
            bool saved = false;
            try
            {
                using (var context = CustomerContext.OpenSession())
                {
                    using (var transaction = context.BeginTransaction())
                    {
                        context.Save(new Customer()
                        {
                            FirstName = customer.FirstName,
                            LastName = customer.LastName,
                            Address = customer.Address,
                            Phone = customer.Phone,
                            CreditLimit = customer.CreditLimit,
                            CustomerSince = customer.CustomerSince
                        });
                        transaction.Commit();
                    }
                }
                saved = true;
            }
            catch (Exception ex)
            {
                //Log here
                throw ex;   
            }
            return saved;
        }
        public CustomerViewModel GetCustomer(int customerId)
        {
            using (var context = CustomerContext.OpenSession())
            {
                return context.Query<Customer>().Where(c => c.Id == customerId).Select(c => new CustomerViewModel()
                {
                    Id = c.Id,
                    FirstName = c.FirstName,
                    LastName = c.LastName,
                    Address = c.Address,
                    Phone = c.Phone,
                    CreditLimit = c.CreditLimit,
                    CustomerSince = c.CustomerSince
                }).FirstOrDefault();
            }
        }

        public bool UpdateCustomer(CustomerViewModel customer)
        {
            bool saved = false;
            try
            {
                using (var context = CustomerContext.OpenSession())
                {
                    using (var transaction = context.BeginTransaction())
                    {
                        var existingCustomer = context.Query<Customer>().Where(c => c.Id == customer.Id).FirstOrDefault();
                        existingCustomer.FirstName = customer.FirstName;
                        existingCustomer.LastName = customer.LastName;
                        existingCustomer.Address = customer.Address;
                        existingCustomer.Phone = customer.Phone;
                        existingCustomer.CreditLimit = customer.CreditLimit;
                        existingCustomer.CustomerSince = customer.CustomerSince;
                        context.SaveOrUpdate(existingCustomer);
                        transaction.Commit();
                    }
                }
                saved = true;
            }
            catch (Exception ex)
            {
                //Log here
                throw ex;
            }
            return saved;
        }

        public void DeleteCustomer(int customerId)
        {
            using (var context = CustomerContext.OpenSession())
            {
                using (var transaction = context.BeginTransaction())
                {
                    var existingCustomer = context.Query<Customer>().Where(c => c.Id == customerId).FirstOrDefault();
                    context.Delete(existingCustomer);
                    transaction.Commit();
                }
            }
        }
        #endregion

    }

8. And in our controller. Below are the controller functions.

public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

        public ActionResult DeleteCustomer(int customerId) {
            ICustomerProvider provider = new CustomerViewModel();
            provider.DeleteCustomer(customerId);
            return PartialView("CustomerList", provider.GetCustomers());
        }

        public ActionResult CustomerList() {
            ICustomerProvider provider = new CustomerViewModel();
            return PartialView(provider.GetCustomers());
        }

        public ActionResult SaveCustomer([Bind(Exclude="Id")]CustomerViewModel customer) {
            ICustomerProvider provider = new CustomerViewModel();
            bool saved = provider.AddCustomer(customer);
            return Json(new { saved = saved }, JsonRequestBehavior.AllowGet);
        }

        public ActionResult UpdateCustomer([Bind]CustomerViewModel customer)
        {
            ICustomerProvider provider = new CustomerViewModel();
            bool saved = provider.UpdateCustomer(customer);
            return Json(new { saved = saved }, JsonRequestBehavior.AllowGet);
        }
        public JsonResult GetCustomer(int customerId)
        {
            ICustomerProvider provider = new CustomerViewModel();
            return Json(new { customer = provider.GetCustomer(customerId) }, JsonRequestBehavior.AllowGet);
        }
}

 

9. As you can see below, I have a very simple form. Don’t worry the source code is in github for you to look the entire running source.

– What I would like to highlight here is the data-bind attribute. The values and click events are bound to our js viewmodel.

@{
    Layout = "/Views/Shared/_Layout.cshtml";
    ViewBag.Title = "Customers";
}
<div class="row container">
    <h2>Customer List</h2>
    <br />
</div>

<div data-bind="visible: formVisible" class="container col-md-12">
    <div class="row margin-bottom-10">
        @ViewBag.Message
    </div>
    <div class="row">
        <div class="column">
            First Name
        </div>
        <div class="column">
            <input type="text" id="firstName" name="firstName" class="form-control" data-bind="value: firstName" />
        </div>
    </div>
    <div class="row">
        <div class="column">
            Last Name
        </div>
        <div class="column">
            <input type="text" id="lastName" name="lastName" class="form-control" data-bind="value: lastName" />
        </div>
    </div>
    <div class="row">
        <div class="column">
            Address
        </div>
        <div class="column">
            <input type="text" id="address" name="address" class="form-control" data-bind="value: address" />
        </div>
    </div>
    <div class="row">
        <div class="column">
            Phone
        </div>
        <div class="column">
            <input type="text" id="phone" name="phone" class="form-control" data-bind="value: phone" />
        </div>
    </div>
    <div class="row">
        <div class="column">
            Credit Limit
        </div>
        <div class="column">
            <input type="text" id="creditLimit" name="creditLimit" class="form-control" data-bind="value: creditLimit" />
        </div>
    </div>
    <div class="row">
        <div class="column">
            Customer Since
        </div>
        <div class="column">
            <input type="text" id="customerSince" name="customerSince" class="form-control" data-bind="value: customerSince" placeholder="yyyy-MM-dd" />
        </div>
    </div>
    <div class="row">
        <div class="column">
            &nbsp;
        </div>
        <div class="column">
            <input type="button" class="btn-info" value="Submit" data-bind="click: function() { submitForm() }" />
            <input type="button" class="btn-danger" value="Cancel" data-bind="click: hideForm" />
        </div>
    </div>
</div>
<br />
<div class="container col-md-12 margin-bottom-10 align-content-right">
    <br />
    <input type="button" class="btn-info" value="Add New Customer" data-bind="click: $root.showForm" /><br /><br />
</div>
<div id="customerlist" class="container col-md-12">
    @Html.Action("CustomerList", "Home")
</div>
@section scripts {
    <script src="~/Scripts/PageScripts/customers.js"></script>
}

 

10. And finally, our knockout view model.

function AppViewModel() {
    var self = this;
    //Since i hide and show the form to prevent turnaround from the server I created an observable property which is bound to the visibility of the form element.
    self.formVisible = ko.observable(false);

    //Here I instantiated all the properties bound to the input elements.
    self.firstName = ko.observable('');
    self.lastName = ko.observable('');
    self.address = ko.observable('');
    self.phone = ko.observable('');
    self.creditLimit = ko.observable('');
    self.customerSince = ko.observable('');
    self.customerId = ko.observable('');

    //Another property to toggle between add new and edit functionality.
    self.isEdit = ko.observable(false);

    //A function for showing the form which is called from the UI.
    self.showForm = function () {
        self.formVisible(true);
        self.resetForm();
        self.isEdit(false);
    };

    //A function for hiding the form which is called from the UI.
    self.hideForm = function () {
        self.formVisible(false);
    };

    //A function for resetting the values of the form.
    self.resetForm = function () {
        self.firstName('');
        self.lastName('');
        self.address('');
        self.phone('');
        self.creditLimit('');
        self.customerSince('');
    };

    //A function for getting the correct date.
    self.getCorrectDate = function (rawDate) {
        var dateStringValue = rawDate;
        var value = new Date (parseInt(dateStringValue.replace(/(^.*\()|([+-].*$)/g, '')));
        var correctDate = value.getFullYear() + '-' + value.getMonth() + 1 + "-" + value.getDate();
        return correctDate;
    }

    //A function which updates a customer
    self.editCustomer = function (id) {
        $.ajax({
            url: '/Home/GetCustomer',
            data: {
                customerId: id
            },
            success: function (data) {
                self.formVisible(true);
                self.isEdit(true);
                self.firstName(data.customer.FirstName);
                self.lastName(data.customer.LastName);
                self.address(data.customer.Address);
                self.phone(data.customer.Phone);
                self.creditLimit(data.customer.CreditLimit);
                self.customerSince(self.getCorrectDate(data.customer.CustomerSince));
                self.customerId(data.customer.Id);
            }
        });
    };

    //A function for deleting a customer
    self.deleteCustomer = function (id) {
        $.ajax({
            url: '/Home/DeleteCustomer',
            data: {
                customerId : id
            },
            success: function (data) {
                $("#customerlist").html(data);
            }
        });
    }

    //A function for loading the customer view via ajax.
    self.loadCustomers = function () {
        $.ajax({
            url: '/Home/CustomerList',
            success: function (data) {
                $("#customerlist").html(data);
            }
        });
    };

    //The function for updating and adding a customer.
    self.submitForm = function () {
        var url = '/Home/SaveCustomer';
        if (self.isEdit()) {
            url = '/Home/UpdateCustomer';
        } 
        $.ajax({
            url: url,
            data: {
                firstName: self.firstName(),
                lastName: self.lastName(),
                address: self.address(),
                phone: self.phone(),
                creditLimit: self.creditLimit(),
                customerSince: self.customerSince(),
                id: self.customerId()
            },
            success: function (data) {
                if (String(data.saved) == 'true') {
                    self.formVisible(false);
                    self.loadCustomers();
                }
            }
        });
    };
}

//Now here is the important part. Tell knockout to apply the necessary bindings between our dom elements and the above model.
ko.applyBindings(new AppViewModel());

 

And we are done. You now have a simple CRUD using NHibernate, FluentNHibernate, Knockout, and Bootstrap. The entire source is in github.

Get the entire source here https://github.com/francorobles/Blog/tree/master/CustomerSite.

Unit Testing JS with Jasmine and Chutzpah

Gone are the days where we will manually test our web sites specially if its using Javascript. Since the arrival of QUnit, Jasmine, and Mocha  the way we test the client side of our sites has changed. Now for this post I will be using Jasmine. Why Jasmine? Because, it support’s Ajax testing. I am not saying that you cannot test ajax results from the other 2 frameworks but Jasmine is just my favorite.

And if you want to integrate it with visual studio with a test runner, let’s use another open source tool

1. Okay first let’s add our test runner to visual studio.

– Go to Tools > Extensions and updates and search for Chutzpah

– Now you should see 2 results. The first one is the Test Adapter and the second is an addition to the context menu. Download them both.

Chutzpah

2. Lets get Jasmine using from Github.

– Go to your github command line and clone it from https://github.com/pivotal/jasmine.git. And add a reference to Jasmine into your solution.

gitclone

 

– Now that I have Jasmine, and with the help of Chutzpah. I can now create a simple test run in test explorer.

Testexplorer

 

Now, how about that? Easy isn’t it? As I said before, you can even test your ajax requests with Jasmine. The beautiful part is with the help of Chutzpah, I was able to load all these javascript test items into the test explorer. If you like my post, please go to my site as well www.francorobles.com.

 

Create a free website or blog at WordPress.com.

Up ↑