Dailycode.info

Short solution for short problems

AngularJS : Smart table select search not working in IE 11

I was building a web site and testing it in Chrome. Worked fine. Untill the users started testing in IE!! There the filtering in the table using dropdowns (select) didn't work. After some looking around I found out that the smarttable was binding to the input event. But IE only fires the change event with select. So the binding didn't work. The smarttable version 2.1.8 has an option to bind the search to another event:

<select st-input-event="change" st-search="Month" class="form-control">
    <option value="">All</option>
    <option ng-repeat="row in vm.filteredConsignments | unique:'Month'" value="{{row.Month}}">{{row.Month}}</option>
</select>

The st-input-event attribute allows you to change the binding. Now it can work with the change event, it still works in Chrome, but now also in IE (in my case IE11).




AngularJS and .Net WEB.API: 405 (Method Not Allowed) for PUT and DELETE

I was having some problems with put and deletes. When I ran the code on the localhost, no problem, but after installing on the servers, delete calls were giving CORS errors. I tried to figure out what was going on, but I lost some time. First I rewrote the methods to POST methods, this worked. But when a new occasion came to look for a better solution I found it here.

The thing is that DELETE and PUT are sending a OPTION request first to the API on the server. If this method is not there, then it will not work. The error message will not really point you into the right direction. 

But instead of adding the OPTION methods foreach DELETE or PUT you could also disable WebDAV in IIS. That really does the trick. No code changes needed, just a simple configuration.

<system.webServer>
  <modules runAllManagedModulesForAllRequests="true">
    <remove name="WebDAVModule"/>
  </modules>
  <handlers>
    <remove name="WebDAV" />
  </handlers>
</system.webServer>

And thatis it.

No more of these now:



AngularJS: How to build your own translation service PART 2

Ruben continued on the translation service blog resulting in a language picker that translates your entire site. You can find the post here:

How to – Build your own Angular translation service – Part 2 

Looking forward to PART 3 where Ruben B from Spikes will show how to implement json files to handle the translations, this way you can get the text from "any" data source.


AngularJS: How to build your own translation service

Ruben Biesemans started a post on how to implement your own translation service. Why you might ask. For him mainly educational purpose, for us, it's an opportunity to have a guideline on how to build your own translation service. Because many might find the existing solutions to complex or just not flexible enough. Here's a link to the part 1 and looking forward to the next part.

How to – Build your own Angular translation service – Part 1

spikesapps.wordpress.com

Intro This will be a first in a series of posts in which I will build a translation service for Angular from the ground up. I want to point out up front that I know there are multiple angular trans… read more here


AngularJS: Authorize app

Ruben of Spikes provides a detailed implementation of using windows authentication to authorize Angular apps. In this case using the UI-router.

Spikes Apps

In my previous post I explained how to set up windows authentication in an Angular application.

In this post I will explain how to implement authorization in the application based on the authenticated user.

I’m starting this post with the code base of the previous post.

Extending the Web API

I’ll extend the API with a new model, AppUser, which will contain the user information that is necessary for Authorization in the application.

Next I will change the WinAuthController. I’m returning an instance of the AppUser object when the user is successfully authenticated.

Typically, you would want to load the information from a database or something. To keep things simple, I’m just returning the domain name and a fixed role.

Extending the Angular application

In the Angular application, I’m moving the AuthenticationService into a separate Angularmodule, which I’m calling ‘debiese.security’. I’ll also add an AuthorizationService

View original post


AngularJS and Windows authentication

We are starting up several Anguar JS (in typescript) projects with an .Net WebAPI2 background. This is really an pleasure to work with, it's like playing with lego when you're 10 years old. Keep building and inventing new things.

One of the things that all applications require is security. Inside our application we can use windows authentication. To set this up was really easy, that is, to set it up for simple GET requests. But with POSTS it gets more tricky. Ruben Biesemans from SPIKES explains this in details here: 

How to implement Windows Authentication in an AngularJS application with a stand-alone Web API

Hope this will help solving this nasty preflight errors. 


Download a UTF-8 (with BOM) csv file from API with javascript

I had a webservice that generated a csv file. At first everything seemed ok. But when de users start testing, there were problems with special characters like ë and é and more  when the csv was opened with Excel. With notepad there were no problems. 
A colleague found out that it had something todo with UTF-8 witout BOM. If we changed the encoding to utf-8 (with BOM) then it opened correct in Excel. 
Now I first started to change  the API, trying all kinds of fixes. But at the end it was the front end were the problem occurred. The API side (.Net) looked like this:

#region Export
[Route("GetExport")]
[HttpPost]
[EnableCors(origins: "http://myserver.be", headers: "*", methods: "POST, OPTIONS", exposedHeaders: "Content-Disposition,MyFileName", SupportsCredentials =true)]
public HttpResponseMessage GetExport(BusinessObjects.ExportRequest request)
{
    this.LogMessage("GetExport IN API", JsonConvert.SerializeObject(request));
    HttpResponseMessage resultMessage;            

    if (request != null && request.IsValid())
    {

        var content = "Joëlle;Mark;Peter";
        var encoding = Encoding.UTF8;
        resultMessage = new HttpResponseMessage(HttpStatusCode.OK);
        resultMessage.Content = new StringContent(content, encoding, "text/csv");
        resultMessage.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
        {
            FileName = request.GetFileNameForRequest()
        };
        resultMessage.Content.Headers.Add("MyFileName", request.GetFileNameForRequest());
    }
    else
    {
        resultMessage = new HttpResponseMessage(HttpStatusCode.BadRequest)
        {
            Content = new StringContent("Invalid ExportRequest.")
        };
    }

    return resultMessage;
}

Up to here everything was working ok. I found out that the problem was rather on the client side were I was getting the file:

There were 2 implementations (first for internet explorer, second for real browsers):

if (window.navigator.msSaveOrOpenBlob) { //Source: http://stackoverflow.com/questions/17836273/export-javascript-data-to-csv-file-without-server-interaction
    var blob = new Blob([decodeURIComponent(encodeURI(rslt.data.toString()))], {
        type: "text/csv;charset=utf-8"
    });
    navigator.msSaveBlob(blob, rslt.fileName);
}
else {
    var element = angular.element("<a/>");
    element.attr({
        href: "data:attachment/csv;charset=utf-8" + encodeURI(rslt.data.toString()),
        target: "_blank",
        download: (rslt.fileName) 
    })[0].click();
}

Now the only thing that did the trick was adding UTF-8 BOM at the start of the text. It was a little different for IE and the rest of the world.

if (window.navigator.msSaveOrOpenBlob) { //Source: http://stackoverflow.com/questions/17836273/export-javascript-data-to-csv-file-without-server-interaction
    var blob = new Blob([decodeURIComponent(encodeURI('\ufeff'+rslt.data.toString()))], {
        type: "text/csv;charset=utf-8"
    });
    navigator.msSaveBlob(blob, rslt.fileName);
}
else {
    var element = angular.element("<a/>");
    element.attr({
        href: "data:attachment/csv;charset=utf-8,%EF%BB%BF" + encodeURI(rslt.data.toString()),
        target: "_blank",
        download: (rslt.fileName) 
    })[0].click();
}

Now when I open the downloaded file in Excel, the special characters are showing fine.


Web API call Json object is null

I have a WCF service that call's a Web API 2 service. I serialize the object ot JSON and pass it to the API. But when deployed to the server the incoming object was null. I had a very hard time figuring out what was the problem, the server only teturned this message:

The remote server returned an error: (500) Internal Server Error

The code to call the web API was something like this:

using (var client = new WebClient())

{

    //var employeeJson = new JavaScriptSerializer().Serialize(empBDO);

    var empJson = JsonConvert.SerializeObject(empBDO);

 

    client.Headers[HttpRequestHeader.ContentType] = "application/json";

    empJson.LogMessage(CurrentProject, LoggingMode.Debug, "JSON to send");

 

    try

    {

        var response = client.UploadString(apiUrl, empJson);

    }

    catch (Exception apiex)

    {

        ("PostToAPI.CallAPI error = " + apiex.Message).LogMessage(CurrentProject, LoggingMode.Debug, apiex.StackTrace);

    }

}

If I called the API from an angular app with the same json that was logged, there was no problem. Everything worked. Then I started to add more and more logging and noticed that the incoming object in the API was null if I called it from the server.

At the end I had to add this line of code to the webclient that was calling the API:

    client.Encoding = UTF8Encoding.UTF8;

So the code looked like this:

using (var client = new WebClient())

{

    var empJson = JsonConvert.SerializeObject(empBDO);

    client.Headers[HttpRequestHeader.ContentType] = "application/json";

    client.Encoding = UTF8Encoding.UTF8;

    try

    {

        var response = client.UploadString(apiUrl, empJson);

    }

    catch (Exception apiex)

    {

        ("PostToAPI.CallAPI error = " + apiex.Message).LogMessage(CurrentProject, LoggingMode.Debug, apiex.StackTrace);

    }

}