Android – Galaxy S7 Edge – SMS Hyperlink Bug (URL’s with # hash or hashtag)

I’m currently working on an application that sends text messages to some of its users.  In that text message we send a URL for the end user to click.  iOS, Windows Phone, and Android will all show their end users a link for the URL so they can easily click it right from their messaging app!  Great!  Except one thing…

Android does not support hash/hashtag/number sign/hashbang/whatever you call it URL’s!

So if you send a URL like, https://appdomain.com/#/login, the Android user will be sent to https://appdomain.com/ while iOS and Windows Phone will direct their users correctly.

I tried searching around to see if I can find a reason for it, but alas to no avail.

My workaround was to create a page, https://appdomain.com/redirect/ which took in the same query string variables, and just used raw JavaScript to send the user to the correct URL (window.location).  SMS message URL link was tested on iOS, Windows Phone, and Android and all three worked!

*Side note:  I believe the “perfect” long term solution would be to use a “URL Shortening Service”.*

AngularJS and MomentJS – Formatting UTC to local time using a custom filter

Frequently in our app, we need to show date/time’s which are stored in our database as UTC time.  From a users perspective however, it is best to view datetime’s in their local timezones.

MomentJS is a great library that is used pretty heavily to display date/time’s in JavaScript in a friendly manner.  Combining MomentJS with AngularJS (and with a small custom filter).

We use “angular-moment” which provides Moment.JS directives for Angular.JS (timeago and more).

https://github.com/urish/angular-moment

We also like to have some conformity for formatting date/times throughout our app. Centralizing the formatting allows use to easily change the style/layout/format of our date/time’s and have that change occur throughout our entire app!

Once you have “angular-moment” running in your AngularJS app, add the custom filter to your AngularJS app.

Our custom filter: (where “angularJSApp” is the name of your AngularJS app)

var angularJSApp = angular.module('angularJSApp', ['angularMoment']);

angularJSApp.filter('UTCToNow', ['moment', function (moment) {
     return function (input, format) {
            if(format)
            {
                return moment.utc(input).local().format('dddd, MMMM Do YYYY, h:mm:ss a');
            }
            else
            {
                return moment.utc(input).local();
            }
        };
    }]
);

How to use the custom filter in our HTML:

{{dateCreated | UTCToNow: true }}
<br />
<span am-time-ago="dateCreated | UTCToNow"></span>

You should now see your date/time in your local timezone

AngularJS UI Bootstrap – Typeahead – Filtering by multiple properties with custom template

I’ve been working on an AngularJS v1.4.7 application that uses “angular-ui-bootstrap” v 1.1 to incorporate Bootstrap components in our AngularJS app.

UI Bootstrap Bootstrap components written in pure AngularJS by the AngularUI Team
https://angular-ui.github.io/bootstrap/

We have been using the “Typeahead” component pretty heavily and I just wanted to make a quick post about how we are using the component, specifically with regards to the custom template, and the ability to filter by multiple items.

https://angular-ui.github.io/bootstrap/#/typeahead

We use the Typeahead component to list objects and allow user selection. Below is a code snippet which shows an AngularJS Bootstrap UI Typeahead component which is filtering on a persons first name, or last name and is using a custom HTML template to display results.

<input type="text" ng-model="cctrl.Person" typeahead-template-url="personTemplate" typeahead-min-length="0" uib-typeahead="person as (person.first_name + ' ' +person.last_name) for person in cctrl.data | filter:{name:$viewValue}" class="form-control" placeholder="Select person" />
<script type="text/ng-template" id="personTemplate">
<a>
     {{match.model.first_name}}&nbsp;{{match.model.first_name}}
     <div class="row small-text">
          <div class="col-sm-4">
               <strong>Address</strong>
               {{match.model.address1}}&nbsp;{{match.model.address2}}
               <br/>
               {{match.model.city}},{{match.model.state}} {{match.model.zipCode}}
          </div>
          <div class="col-sm-4">
               <strong>Phone</strong>
               <br/>
               {{match.model.phone}}
          </div>
          <div class="col-sm-4">
               <strong>Email</strong>
               <br/>
               {{match.model.email}}
          </div>
     </div>
     <hr />
</a>
</script>

The “uib-typeahead” attribute is where you put what fields you would like to filter by.

uib-typeahead="person as (person.first_name + ' ' +person.last_name) for person in cctrl.data | filter:{name:$viewValue}" class="form-control"

If you want to add email and phone filtering to the Typeahead you would just add a space behind your last filter, and then add the new filter you want.

uib-typeahead="person as (person.first_name + ' ' +person.last_name + ' ' + person.email + ' ' + person.phone) for person in cctrl.data | filter:{name:$viewValue}" class="form-control"

The template is just controlled by the “typeahead-template-url” attribute on the Typeahead element and the HTML contained within the “” element. Whatever ID you give your script element will be the value for your “typeahead-template-url” attribute.

typeahead-template-url="personTemplate"
<script type="text/ng-template" id="personTemplate">
</script>