AngularJS creating multiple $resource endpoints in a service

So this had me baffled for a bit. For using Angular’s $resource in your Angular service, you map it to a particular URL with (optional) parameters defined for that URL. Then how can you have multiple resources with their own unique URLs mapped in the same service?

For example, here’s a service called User which maps to the URL “/api/users/…”:

angular.module('myApp')
  .factory('User', function($resource) {
    return $resource('/api/users/:id/:controller', {
      id: '@_id'
    }, {
      changePassword: {
        method: 'PUT',
        params: {
          controller: 'password'
        }
      },
      get: {
        method: 'GET',
        params: {
          id: 'me'
        }
      }
    });
  });

As you can see, there’s one resource in this service that maps to the one URL, so then how can I add another URL for the $resource?

The answer turned out to be pretty simple, actually. What you have to do is create an object (JSON) of $resources that are returned for the service. You can have individual elements inside the object that each map to a different $resource. So, for example:

'use strict';

angular.module('myApp')
  .factory('User', function ($resource) {
    return {
      WithId: $resource(
        '/api/users/:id/:controller',
        {
          id: '@_id'
        },
        {
          changePassword: {
            method: 'PUT',
            params: {
              controller: 'password'
            }
          },
        }
      ),
      Misc: $resource(
        '/api/users/misc/:controller',
        null,
        {
          generateResetPasswordToken: {
            method: 'POST',
            params: {
              controller: 'generateResetPasswordToken'
            }
          },
        }
      ),
    };
  });

In the above example, in the “User” service, we have two resources that can be accessed. To access “changePassword”, we can use User.WithId.changePassword (which maps to a particular URL), and to access “generateResetPasswordToken” we use User.Misc.generateResetPasswordToken (which maps to another URL).

Voila!

Adding an asterisk to required fields in Bootstrap

This is pretty useful in giving a visual indication to the user when a form field is required.

The CSS:

.form-group.required .control-label:after {
  content:"*";
  color:red;
}

Then in your HTML:

<form>
  <div class="form-group required">
    <label class="control-label">Required Field</label>
    ...
  </div>
</form>

There will now be a nice little “*” after the label for “Required Field”.

Making a pseudo div fade in using CSS animation

The example I’ll use applies specifically to Vaadin, for when the loading bar is shown if the server is taking too long. However, the same CSS styling I’ll use can be applied to any pseudo div.

When Vaadin loads a page (or a “view”), and if the page takes too long to load, there’s some client side JavaScript and CSS that Vaadin pre-loads, which displays a loading bar or progress bar. This bar progresses forward, from left to right, at the top of the page, under the “URL” area of your browser. And it eventually goes away when the page loads. This gives the user the indication that something is happening and they should wait.

If the page takes too long to load, this bar eventually starts blinking. And if the server is stuck (had a hiccup somewhere), this bar just blinks forever. After some waiting, more adept users eventually realize it will never load and they refresh the page which usually resolves the issue. However less tech-savvy users don’t know what to do at that point. So we set up a small message box (a pseudo div) that floats under the loading bar, which tells the user to refresh the page. This is kind of like what the GMail web app does when there’s a network issue.

First of all, to set up the pseudo div, we add the following to our theme’s scss (SASS) file that Vaadin uses:

.v-loading-indicator-wait:after
{
  position:fixed;
  content: "Temporary Internet issue... Please wait, or refresh page.";
  color: black;
  background-color: #F9EDBE;
  border-style: solid;
  border-color: #F0C36D;
  box-shadow: 2px 2px 5px #888888;
  left: 50%;
  transform: translateX(-50%);
  top: 10px;
  padding-top: 5px;
  padding-right: 5px;
  padding-bottom: 5px;
  padding-left: 5px;
}

“v-loading-indicator-wait” is the style Vaadin gives to the loading bar which shows up after a certain amount of waiting while the server is processing the request. So to show our floating div with the loading message, we can use the ::after (v-loading-indicator-wait::after), as indicated above.

The problem is, that the v-loading-indicator-wait is added after just a number of seconds of waiting (around ~5), and showing the floating div would be too soon. So the best way (or at least an easy way) to do it is to use animation to delay when it is added.

You can define the animation to “fade in” the div (from being invisible to visible) after a certain number of seconds, like so:

@include keyframes(animate-in-scale-up) {
  0% {
    @include transform(scale(0));
  }
}

@-webkit-keyframes fadein {
  0% { opacity: 0; }
  80% { opacity: 0; }
  100% { opacity: 1; }
}

@-moz-keyframes fadein {
  0% { opacity: 0; }
  80% { opacity: 0; }
  100% { opacity: 1; }
}

@-o-keyframes fadein {
  0% { opacity: 0; }
  80% { opacity: 0; }
  100% { opacity: 1; }
}

@keyframes fadein {
  0% { opacity: 0; }
  80% { opacity: 0; }
  100% { opacity: 1; }
}

.v-loading-indicator-wait:after
{
  //...all the other stuff
  -webkit-animation: fadein 12s ease 1 normal;
  -moz-animation: fadein 12s ease 1 normal;
  -o-animation: fadein 12s ease 1 normal;
  animation: fadein 12s ease 1 normal;
}

And viola. The floating div doesn’t show up until about 12 seconds after the “v-loading-indicator-wait” is added, which is about 5 seconds after a request is initiated and the server hasn’t responded. So that’s a total of 17 seconds between the user initiated the request and till when the message shows, which I believe is enough waiting time to realize the server may never respond.

Correctly doing post-login processing in the DaftMonk AngularJS full-stack seed

So I’ve been working on a personal project using the MEAN stack (MongoDB, ExpressJS, AngularJS and NodeJS)! The nerd in me has been pretty excited to learn something completely new and different. I’ve never done full-stack development strictly in JavaScript, and so far I’m finding it to be pretty neat. I’ll be making posts about things I struggle with, or find useful, as I progress.

Anyway, I used the DaftMonk AngularJS full-stack yeoman generator (https://github.com/DaftMonk/generator-angular-fullstack) for my project seed. I definitely recommend it if you’re starting out fresh with MEAN (or even if you’re not), since it speeds up the initial setup and development immensely.

My problem arose as I was wiring up some post-processing to be done after a user logged in. In the login controller (login.controller.js), after the login function is called from the Auth service, there is a function in “.then()” that is called upon success.

Auth.login({
  email: $scope.user.email,
  password: $scope.user.password
})
.then( function() {
    //login was successful
    //...
  }

However, even though the user has logged in, the user data is not available yet! So, you cannot access the current user’s data properties (such as their role) through Auth.getCurrentUser() (for example the Auth.getCurrentUser().role field will be undefined). This is due to the fact that the data is loaded asynchronously (I’m still trying to get the hang of how that works).

The way around this is to use the Auth.isLoggedInAsync(…callback…) function. The callback sent to isLoggedInAsync is called after the user has finally been loaded, which will guarantee your post-login-processing code being executed after the data for the user is available.

This is how you’d make use of Auth.isLoggedInAsync(…):

Auth.login({
  email: $scope.user.email,
  password: $scope.user.password
})
.then( function() {
    Auth.isLoggedInAsync(function(success) {
      //Auth.getCurrentUser() will now return the user with all the properties fully loaded
    }

Enjoy!

Making a Vaadin window transparent/translucent

We had a need to do this recently, and it wasn’t obvious, so I thought I’d share.

One thing to note is that if the window is modal, this trick won’t work. Since for modal windows, Vaadin adds some more styling around the window to the back the background “dimmed”, thus giving a stronger visual focus on the modal window. For regular (non-modal) windows, this trick works great, especially if you just want to overlay some information on content behind the window.

In your java code, add the following style to your Vaadin Window:

myWindow.addStyleName("translucent");

In your theme stylesheet for your application (most likely a “.scss” file), add the following styles:

.v-window-translucent
{
  background-color: rgba(255,255,255,0.6) !important;
}
div.v-window-translucent .v-window-contents {
  background: rgba(255,255,255,0.6);
}

Then compile your theme, and refresh your page. Viola! Your window will now be translucent.

To tweak the translucency, modify the “a” (alpha) value in the rgba inside the theme style. 0.6 worked well for us, making it a bit translucent. To make it less translucent, try a value greater than 0.6. And to make it completely transparent, try 0.

Enjoy!

Resolving Vaadin push with long polling issues in AWS Elastic Beanstalk

This took me a long time to figure out, so I thought I’d share it with anyone else struggling with this.

When you upload a Vaadin application to the AWS Elastic Beanstalk, Tomcat sits behind an Apache server that proxies connections to it. (Note: this may apply to you even if you’re not in AWS/ElasticBeanstalk. If you use Apache as a proxy to an application server, be it Tomcat or something else, this could still be an issue).

If you’re using Vaadin push in long polling mode (Transport.LONG_POLLING), it turns out that the connection between the client (browser) and server (tomcat, or your other java application server) gets dropped due to a timeout issue. If there is no data exchanged between the server (tomcat) and the client (browser), then the connection is deemed “idle” by Apache and gets dropped. This is an issue because with long polling, the HTTP connection remains open indefinitely, and that’s information is pushed to the client from the server.

Now with Vaadin’s push, it’s supposed to recover from a dropped connection. The connection is supposed to just get reestablished, and everything resumes. That’s an ideal scenario. In my experience, that doesn’t always work the way it should. If I’m on a Vaadin web app through my browser, and sit idle for a while, when I come back to it a lot of time it resumes fine (I can see push reestablishing itself in the console), but a lot of times the app just hangs forever.

Another thing to note is that Vaadin sends a heartbeat to the client, to check if the client is still there. The default heartbeat is every 5 minutes. When a heartbeat is sent, Apache’s idle connection timeout is reset. So if there is no user activity for a few minutes, the goal is to adjust the configuration so that the heartbeat happens before Apache times out the HTTP connection.

So the solution for this is to

  1. Modify Apache’s timeout for idle connections. I believe the default setting in AWS’s configuration for Apache, is 60 seconds. You’ll need to ssh into your server, edit /etc/httpd/conf/httpd.conf, and look for the “Timeout” directive. Change the Timeout directive to be greater-than the default Vaadin heartbeat of 5 minutes. Try 6 minutes (note: the Timeout value is in seconds), so you’d set “Timeout 360”. The downside of this approach is if your server has hundreds of thousands of requests, surely some legitimately idle connections (where the client is gone without cleaning up and not coming back) will linger for longer than 60 seconds, this affecting your system performance.
  2. Modify Vaadin’s heartbeat to be less than 60 seconds. You can edit your web.xml, and add an heartbeatInterval parameter like so:
        <context-param>
            <param-name>heartbeatIntervalparam-name>
            <param-value>120param-value>
        context-param>
  3. You can tweak both the Vaadin heartbeat, and the Apache Timeout value to some reasonable values that suit your needs the best. Just make sure that the heartbeat interval is shorter than the timeout.

Enjoy!