• Multi-character Google Maps cluster marker labels

    Multi-character Google Maps cluster marker labels

    Turns out Google Maps API does not allow for more than a single character on marker labels (everything past the first character gets trimmed). Not even stackoverflow was able to provide me with a good way of going around this (take a look at this and this). So, a little digging was required…

    Fortunately, folks who made google-maps-clustering-csharp were able to go around this restriction by implementing a custom “label element” through prototyping the OverlayView element and then using it instead of a string for Marker’s label property. I extracted and cleaned up the code from their MVC application. What’s left is all you need to render markers that support multiple characters (feel free to break it into multiple files – perhaps a service and a controller if you’re using AngularJS or something similar):

    And this is the CSS that’s needed to make it all work (you can find the cluster icons here):

    Cheers!

  • Detecting no-Internet / user-offline in Angular

    Detecting no-Internet / user-offline in Angular

    Sometimes, a user might find himself disconnected from the Internet after he already got to your page. Given the nature of SPA apps, this situation might not be very obvious to the user at first and he might end up thinking that the “site doesn’t work”. If the user goes offline after he already landed on your AngularJS site, the back-end API’s won’t be accessible any more but all the client-side stuff will still remain loaded if the user does not refresh the page. The problem is – because the page is still visible and some events still respond to his input, he might not notice (or even understand) what actually happened.

    This may result with a call from your client. :) To prevent having to explain the whole situation, it might be easier to handle this situation in advance. For example, you could detect if the user is offline and then redirect him to a “warning” or an “error” page (you might want to precache the error page template upon page load).

    There is a very simple way in AngularJS to detect whether the user is disconnected from the Internet or not. Simply use/attach the following http-request-interceptor to your app.

  • Loading embedded resource images into PdfSharp/MigraDoc for non-web projects layers

    Loading embedded resource images into PdfSharp/MigraDoc for non-web projects layers

    There are some cases (for example on Azure) when you can’t really rely on ASP’s Web-layer file resources or “server paths” and file management libraries to access your static resource files. For example if you have a business layer which doesn’t really have a direct access to another layer’s files but you need to generate a PDF using PdfSharp/MigraDoc inside that layer.

    How it can be done is – you need to add an image file to your layer, then right-click on it and go to it’s properties. There you need to set the “Build Action” to Embedded Resource, and the “Copy to Output Directory” to Copy if newer. After that, use these three simple methods to load up the image from the assembly into a Stream, convert it to a byte[] array and then encode it as a base64 string.

    By using the base64 representation of the image, you will be able to embed it into your PDF document.

    Cheers!

  • Pre-caching HTML templates with AngularJS ui-router directive

    Pre-caching HTML templates with AngularJS ui-router directive

    Unless you’re using gulp-angular-templatecache (which you probably should) to bundle your HTML templates into an Angular Javascript module, you might in some cases want to pre-cache certain HTML files. For example if you have a specific “error page” HTML template used to display a specific error message telling the user he lost his Internet connection. If you don’t pre-cache such a template, your Angular app won’t be able to fetch it from the server (because the browser is obviously off-line) and as a consequence it will be unable to display this important message.

    If you’re using ui-router, there is an easy way to pull the template from the server before it’s even used. I like having an abstract root state which I setup in my app.config() (inside app.js) to kind of abstract my base layout. Views from this root state can then be overridden by any child state which is very handy for having a few different types of layouts. For example, some with a sidebar, some without, etc.

    The cool thing about the abstract root state is that it will fetch all templates specified inside its views property even if they’re not used right away and it will put them into Angular’s template cache. The next time any of our child ui-router states requires one of these cached templates, it won’t make a request against the server but it will simply reuse the cached template.

    You can use this simple trick to if needed cache any other templates as well. Obviously don’t overdo it because you want to make the smallest amount of initial requests you can to speed-up the loading time. Or even better – use angular-templatecache, it’s wonderful. :)

    Cheers!

  • Downloading/streaming Azure Storage private container blobs to AngularJS through .net WebAPI

    Downloading/streaming Azure Storage private container blobs to AngularJS through .net WebAPI

    When our Azure storage contains files that are meant to be publically accessible, it’s pretty trivial to deliver them to the end-user. We can either embed such items (e.g. images) or simply add links which point to them (e.g. pdfs) because Azure provides direct links to them. But what happens when these files contain sensitive data that is not meant for just anyone? Perhaps some kind of reports?

    Well, it gets a bit more complicated.. Since these files don’t have publically accessible URI’s any more, there are several steps which we need to go through:

    • Authenticate against Azure using SDK
    • Load the file into MemoryStream
    • Deliver the stream to the client (browser)
    • Convert the byte array into an actual file on the client-side and simulate “downloading”

    Since we’ll need more than just the MemoryStream, we’ll wrap it together with the file metadata into a model object.

    We will use AzureProvider class to authenticate against Azure, download the file from Azure and to create the model object.

    Our actual controller will inherit from this BaseApi class which contains a custom IHttpActionResult method which we can name AzureBlobOk. This is something pretty reusable so it’s good to have it at hand in your base class. What it does is it sets up all the content headers and it attaches the stream as the response content payload . It also returns HTTP status 200 which means OK – everything went fine.

    The actual controller is pretty simple..

    On the client side, we’ll need the following service to actually convert the byte array that we got from the API into something meaningful. I tried various approaches, but in the end decided to use FileSaver.js which “implements the HTML5 W3C saveAs() FileSaver interface in browsers that do not natively support it”. What it will do is turn the byte array into an actual file and prompt the user to download it.

    This service can easily be consumed by injecting it into your AngularJS controllers and calling the .getBlob() function which will do all the heavy lifting for you.

    Hope this helped, enjoy! :)

  • PdfSharp/MigraDoc to Azure Storage in-memory upload

    PdfSharp/MigraDoc to Azure Storage in-memory upload

    From my (somewhat limited) experience PdfSharp/MigraDoc seems like a pretty fine and powerful library for creating .pdf documents, but it’s documentation – not so much. It’s a bit all over the place and with multiple different NuGet versions/builds and outdated StackOverflow code samples not really helping the situation.

    However, creating a .pdf document in-memory and uploading it straight to Azure is not really that complicated. When might this be useful? For example when you need to generate a report but instead of immediately giving it to the user it just needs to get stored for later access.

    Magic word we’re looking for is MemoryStream. We’ll use two classes – one which will take a MemoryStream and upload it to Azure (AzureProvider.cs), and another one which will create a very simple MigraDoc document (ReportProvider.cs) which you can then build upon and then feed that document to the AzureProvider in the form of MemoryStream.

    The code is pretty straightforward and looks like this:

    Somewhat related – in the next post I’ll explain how to stream a file from Azure Storage private container through .net WebAPI to an AngularJS app.

Back to top