Ben Nadel builds an “Incident Commander” application that allows him to transform updates into consistently formatted Slack messages. The application is built in Angular 4 and caches incident data in localStorage….
Ben Nadel builds an “Incident Commander” application that allows him to transform updates into consistently formatted Slack messages. The application is built in Angular 4 and caches incident data in localStorage….
Ben Nadel builds on his previous post about retry behavior for MySQL transaction lock timeouts, this time making the approach generic by factoring out the logic around which errors warrant a retry….
It’s been a couple of month since we’ve last run our training in the USA, so we are very pleased to announce that our Angular Master Class is coming to Houston in August!
You or your team should attend our 4-day Angular Master Class training.
We have also updated our course and lab exercises to Angular Material and Angular Flex-Layout, you can read about that here:
Revamped Angular Master Class.
This is the first time we’ll run a public 4-day training! The reason we added another day is because we want to teach our brand new material on Redux and ngrx.
If you would like private, on-site training for a team of 10 or more developers, please contact us at firstname.lastname@example.org.
And we found the perfect, artsy venue that will get everyone into the right piece of mind to learn the nuances and power of Angular.
The event takes place on the August 22 – 25, 2017 in the Bisong Art Gallery.
Click on the picture above to see the map to the venue location.
These are intense, full 8-hour days… but don’t worry, we make the classroom fun. thoughtram teaches the class with two (2) trainers. And almost every 30 minutes, students work with hands-on, coding lab exercises.
We also have social time after class on Day 2 and Day 4. Leverage the social times for networking, offline questions, and simply relaxing with your fellow Angular-philes.
So come to our training, have a blast, and get the best acceleration into Angular possible. And use the public training to expand your Angular community network.
You can find more information on our official event page, or grab your ticket right here!
See you in Houston!
We just returned from Denmark after running yet another Angular Master Class with a very diverse group of attendees from a wide range of different countries.
If you haven’t had the chance to join us in Denmark you really missed out on a fun event! However, here are good news: We are bringing our Angular Master Class to Berlin soon!
We are happy to team up with Westernacher Solutions AG to run the training in a really cool atmosphere with lots of room to teach, learn and have fun!
The event takes place on the 18th to 20th September 2017 in one of the most vibrant parts of the city.
We will have three (3) days of fun and learning the ins and outs of Angular including things like
…and many more!
The early bird round of tickets is on sale now. You can save up to 125,00 € so you’ll better be fast. Seats are very limited with only 5 early bird tickets available!
Come to our training… have a blast and get the best acceleration into Angular possible. You can find more information on our official event page, or grab your ticket right here!
See you in Berlin!
Motion is an important aspect when building modern web applications. In fact, it’s important for all kinds of software products that involve user interfaces and interactions. Good user interfaces with well-designed animations help users understand the flow between two states. Imagine we are on a simple website that only has one button. We click that button and without any motion a box appears. Isn’t that boring? Also, we as a user might think that the box appeared because of our action. However, it could have been the result of something else like an http call in the background. In addition, animations can be used to make the user interface more snappy and responsive. They also explain changes in the arrangement of elements on the screen as some user actions may change the UI.
This could easily drift off into a whole new discussion about user experience and why motion matters. The bottom line is that motion not only makes a site more usable but also more fun. They tell stories, add a perceptible time dimension and improve the overall user experience of applications.
Let’s start with a deeper breath of how animations in the web generally work.
What’s a transition you may ask. Very good question! The Oxford Dictionary defines a transition as follows:
The process or a period of changing from one state or condition to another.
Applied to animations, a transition is the visualization of some state changing over time. A state could be a person sitting at the airport waiting for his plane to be boarded. It’s a condition something or someone is in at a specific point in time. A button on website could have 4 different states –
pressed, where the latter is a combination of
active. We could use a finite state machine or simply state transition system to visualize how it works:
The point is, a “system” or some element on the page can have multiple states. Instead of simply going from state A to B, we’d like to interpolate the values in between. Later in this post we’ll see how to use Angular’s animation system to implement a rich profile animation. For this it is necessary to understand the concept of states and state machines as it is kind of implemented as one. With
transitions we can listen for state changes and act accordingly.
As a matter of fact, we can take advantage of the same hardware acceleration in JavaSript too. It’s as easy as setting a CSS property with a 3D characteristic, such as
matrix3d(). This will push the particular element onto another layer which is then processed by the GPU. The GPU itself is highly optimized for moving pixels making it much for effective for animations compared to the CPU. For more information, check out this great article by Paul Lewis and Paul Irish on high performance animations.
CSS animations do not require any 3rd party libraries. However, there are some tools that make your life much easier, for example libraries that provide pre-defined keyframe animations like Animate.css.
.animate() and specify the properties (e.g. opacity or transform) we’d like to animate. Here is how we’d move a
div to the right by
200px animating its
While this works, it’s better to stick with either the
opacity property as those are the only things a browser can animate cheaply. Note that we use the string
slow to specify the duration of the animation. It is an equivalent for supplying a duration of
Let’s create the same animation as before, but this time using GSAP. More specifically we’ll use TweenLite, a lightweight animation tool that serves as the foundation of GSAP.
Note that the code above requires a plugin called CSSPlugin. This plugin allows us to animate almost any CSS property.
When working with frontend frameworks like Angular it could be a whole new story as some of them handle animations differently.
That doesn’t mean it’s not using some of the core concepts under the hood. They often come with their own animation system. Take Angular’s animation system for example, that is built on top of the Web Animations API (WAAPI). It’s fairly new and currently being implemented in Chrome and Firefox. It’s goal is to unite CSS, JS and SVG. More specifically, it aims to provide the power of CSS performance, add the benefits and flexibility of JS and SVG as well as leave the fundamental work to the browser without the need for additional dependencies.
If you want to learn more about the Web Animation API, check out this series of posts which goes a lot more into detail while covering advanced features like running multiple animations in parallel or in sequence, animating elements along a motion path or controlling animations using the
Here is a snippet showing the WAAPI in action:
Remember, the WAAPI is still a work in progress and things like additive animations are not fully supported yet. That’s why we use
getComputedStyle() to calculate the very first
KeyframeEffect is used to specify the values for the properties we’d like to animate. Each effect represents one keyframe and the values are basically interpolated over time. In other words, the array is a collection of keyframes. Here is an equivalent CSS keyframe animation:
Similar to the WAAPI, we also need to set the initial value when animating the
left property. This is not needed if we were translating the element on the X-axis to another location via its
transform property. With CSS keyframe animations we normally define when the change will happen with either percentage values or the keywords
to, which are the same as
We do this with the WAAPI by defining an
offset for each set of property values (keyframe). Keyframes without any offset will have offsets computed, e.g. the first keyframe has an offset of
0, the last will be
Enough about theory! Let’s build a simple modal-based user profile and apply animations to improve the user experience and draw focused-attention to the dialog.
Here’s a preview of what we are going to build:
Our application is going to be very simple and mainly consists of two components:
DashboardComponent is the entry point (root component) of our application. It contains almost no logic and merely represents a wrapper composing the
DashboardComponent we initialize the data for the user profile and toggle the visibility of the dialog. An
ngIf will then show and hide the template. This is important for our animation because we use it as a trigger.
Here is the template of the
So far so good. Let’s look at the template of
To achieve the desired animation we need to set some initial CSS properties to enable 3D-space for the children elements inside
ProfileDetailsComponent. We do that by setting the
perspective on the
host element. CSS host selectors are a great way to apply styles without introducing an additional wrapper element.
Nonetheless, for our animation we still need a wrapper element because the
perspective property doesn’t affect how the host element is rendered; it simply enables 3D-space for children elements.
Again, the perspective only affects children elements and only those that are transformed in a three-dimensional space, e.g. rotation about X-axis or translation along Z-axis. The value for the perspective determines the strength of the 3D-effect. In other words, it describes the distance between the object and the viewer. Therefore, if the value is very small the effect will be quite impressive as we are extremely close to the object. On the other hand, if the value is high the distance between the object and the viewer will be large and therefore the animation looks rather subtle. That said, we need to set the
perspective property in order to achieve 3D-effects.
In addition, we have to specify a point of origin for our upcoming transformation. By default the point of origin is exactly the center of any element. The rest is just simple styling for the dialog.
Alright. Now that we got this in place, let’s implement our animation imperatively using GreenSocks’s timeline feature.
A timeline is basically a container where we place tweens over the course of time. Tweening is the process of generating intermediate frames between two states. With GSAP’s timeline we can easily build sequences of animations and animate an element
.from() a certain state. In addition, we get a lot of control over our animations. As such, we can stop, pause, resume, or even reverse them. Here is a simple example:
Check out the demo and try it out!
TimelineLite we have complete control over where tweens are placed on the timeline and they can overlap as much as we want. Notice how we use
.add() to add a label to the timeline. We can use labels to start multiple animations at the same time. For instance, we use this mechanism to run two animations in parallel. The
h1 will fade and translate in at the same time. Both animations could easily be combined in a single animation, but they have different easing functions. It solely demonstrates how to use labels.
Let’s see how we can do that in our Angular application. First off, we get all the elements using Angular’s built-in
@ViewChildren() decorators. We leverage those to query specific elements within the view of a component.
@ViewChild() returns an
@ViewChildren() returns a
QueryList. Essentially it’s an object that stores a list of elements and implements the
iterable interface. This makes it possible to be used in combination with
ngFor. The cool thing is that it’s based on Observables. This means we can subscribe to changes and get notified whenever an element is added, removed, or moved.
For more information check out Minko’s blog post about the difference between view children and content children in Angular.
Here’s how we use it in our Angular application to grab the elements we need:
The decorator takes either a type or a template reference variable. In most cases, such template reference variable is a reference to a DOM element inside a component’s template. The following snippet shows how we’d get a reference to the
#wrapper? That’s how we declare a local template reference for that specific element. We do this for all the elements we need for the animation. With that in place, we can instantiate our timeline.
Usually we use
ngOnInit to implement our initialization logic. However, this is a little bit too early in a component’s lifecycle because we have to wait for the component to be fully initialized in order to use the DOM elements we collected. There’s a lifecycle hook called
ngAfterViewInit which is the perfect moment in a component’s initialization process in which we have everything we need to set up the timeline.
Cool! But before we can construct the timeline for our profile animation there’s one thing left to do. We need to apply an initial transformation to the
wrapper element via CSS in order to achieve the fancy 3D-effect:
We can now apply the concepts we learned to build the timeline:
Woah! This looks pretty overwhelming at first glance. But all we have to do is to orchestrate our animation using GreenSock’s timeline API. With the help of labels we can run multiple animations in parallel and precisely control the timing of certain animations.
One thing we haven’t talked about so far is
.staggerFrom(). A stagger is an animation that contains a delay between each successive animation.
The whole animation can be illustrated as follows:
Here’s the full-fledge solution. Take a look and fiddle with it.
In the previous section we have seen how to implement the profile animation with GreenSock in an imperative way. There are some drawbacks to that solution. First, it’s quite some boilerplate and work to collect all the elements and manually set up the timeline. That said, an animation platform like GSAP requires the DOM to be ready. A framework can make much more assumptions about the instructions (animation data) and the environment (app and browser) before animating things. Second, it can be very beneficial if there’s a framework backing the animation engine, like with Angular. GSAP and other animation libraries cannot easily handle DOM insertions or removals because they do not own the DOM transactions. Angular on the other hand has full control over the DOM.
If you are completely new to animations with Angular, check out this post by Thomas Burleson. It covers the fundamentals and shows an example of a more complex fade animation.
Alright, let’s refactor our profile animation using the latest animation features introduced with Angular 4.2. To get started, we first have to import the
@angular/platform-browser/animations and add it to the
imports of our application:
Remember, animations in Angular are based on the WAAPI and work in browsers that support it including Chrome and Firefox. However, currently Internet Explorer and Safari do not. In this case a polyfill is required to achieve similar results. Once animations are properly imported and enabled, we can go ahead and start defining the profile animation.
To quickly recap, animations are declared with the animations metadata property within the
@Component() decorator. Each animation is defined by a
trigger which takes a name and a list of
transition entries. Angular’s animation engine works basically like a state machine. That’s right. This should sound familiar. We have seen it in the beginning of this post, remember? The first argument of
transition allows you to specify a direction from one state to another, also known as state-change-expression. Here are some common values:
* => *captures a state change between any states
void => *captures the entering of elements
* => voidcaptures the leaving of elements
The last two are so common that they have their own aliases:
void => *
* => void
Angular 4.2 introduces several new animation features and extends Angular’s animation DSL. Here’s a quick overview of what’s new:
Neat! Let’s use that to re-implement our profile animation with Angular’s animation DSL. In order to demonstrate most of the above animation helpers, especially
animateChild(), we need to refactor our application a bit.
First of all, we create a new component called
ProfileStatsComponent which now contains the
ul that was previously part of the
DashboardComponent. The template of the
DashboardComponent now looks like this:
The dashboard now composes the
ProfileStatsComponent which will later define its own animation. For now, let’s focus on the profile animation and talk about child animations in a minute.
Here’s how we define our
profileAnimation we define one
transition and on
:enter (when the dialog enters the DOM) we run several animations in parallel. Next, we use
query() to grab the DOM elements we need for our animation and set some initial styles using the
Remember how we collected the DOM elements using
@ViewChildren()? We don’t need to do that anymore. Plus, we can get rid of all the local template references because that is now handled by
query(). Quite powerful, huh?
Before we implement the profile animation, let’s create a reusable fade animation that we can use elsewhere in different places with full input parameter support:
fadeAnimation can now be imported into our application, adjusted via input parameter and invoked using
useAnimation(). The values we specified for the input parameters are default values.
Once we have that in place, let’s add the missing pieces to our animation:
In the code above, we query a bunch of elements and use several animation helpers to achieve the desired effect. All animations will run in parallel because they are defined within a
group(). Also, there are no “labels” or a similar feature to what GreenSock provides with
.add(). Turns out, Angular has no timeline support yet and we need to fiddle with delays in order to orchestrate the animation.
If we take a closer look we can see that there’s actually more to it. For instance for the
wrapper, we run two animations in parallel one of which is the reusable animation we defined earlier. We can invoke a reusable animation with the
useAnimation() method. While
AnimationOptions are optional, we specify them to override the default input paramters.
Furthermore, we can spot this special style property of
style('*'). This will basically remove all of the special styling we have added (e.g. initial styles) and reset the state of the element. It’s an equivalent of setting each value to
*. This means that Angular will figure out the values at runtime. On top of that use the
stagger() animation helper method to animate multiple elements with a time gap in between each animated element.
Ok, but how do we use the animation? For that we can either attach the trigger to the element within the component’s template or use a
@HostBinding(). In our case, we use the
@HostBinding() because we want to attach the trigger to the host element:
In a real-world scenario you most likely end up having multiple components and animations on different levels, e.g. parent or child animations. Turns out that parent animations will always get priority and any child animation will be blocked. That’s a shame. But don’t bury your head in the sand yet because Angular got you covered! We can query inner elements and use
animateChild() to allow child animations to run. The cool thing is we can do that at any point in the animation sequence within a defined
In our example, we created a component called
ProfileStatsComponent. Let’s see this in action and start off by creating a child animation for this component using everything we know by now:
Easy, right? Now we can go ahead and use the
animateChild() helper as mentioned earlier in our
That’s it. We fully re-implemented the profile animation using Angular’s built-in animation system. It’s very intuitive, easy to use and declarative.
Here’s the demo. Try it out and fiddle with it!
If you want to find out more about the new animation features in Angular 4.2+, check out this excellent post by Matias Niemela.
Kudos to Matias Niemelä for the amazing work on the Angular Animation system!
Ben Nadel experiments with wrapping database gateways in a “retriable proxy” that will automatically retry transaction lock wait timeout errors in ColdFusion (using MySQL)….
For those may not know, Onsen UI offers a rich variety of UI components and tons of ready to implement features, specially designed for mobile apps. However, with all these possibilities one can’t help but be puzzled about how can all these components be combined to create an app. For that purpose, we in the Onsen UI team will show you how to use a combination of Onsen UI components to create a user interface pattern almost identical to the one of the popular music app Spotify!
First of all, when creating an interface, you must decide how many and what kind of screens (pages) do you need for an app. In this case, our work is cut short, since we will follow the example of an existing app. However, since most of the pages of the actual app are quite similar in design with just slight differences in their functionality, we will limit the number of pages to three:
We shall go through these three pages briefly so that we give you the general idea of how you can easily combine components to create an interface on par with the ones of popular apps. For the complete user interface pattern, please visit our tutorial page.
Note: We will not implement the different functionalities of the interface (except some that are necessary for the flow of the app) since that is not the purpose of this post.
The first page of this pattern is the Browsing Page which allows the users to browse through playlists and find one that suits their tastes. The implementation of this page is quite simple. It’s constructed with the following Onsen UI elements:
On the top, we have a carousel which elements have fixed length to get the overflowing horizontal list look, displaying the list of playlists the app recommends to the user:
[...] <ons-carousel auto-refresh swipeable overscrollable item-width="130px" class="recomended_list"> <ons-carousel-item modifier="nodivider" id="playlist_1" class="recomended_playlist" onclick="openPlaylist(this.id)"> <div class="thumbnail"><ons-icon icon="ion-music-note"></ons-icon></div> <div class="recomended_playlist_title" id="playlist_1_name">Playlist 1</div> </ons-carousel-item> [...] </ons-carousel> [...]
Followed by a standard vertical list, giving more options for categorizing the playlists:
[...] <ons-list class="menu_list"> <ons-list-item class="menu_item" modifier="chevron" tappable><ons-icon icon="line-chart"></ons-icon> Charts</ons-list-item> [...] </ons-list> [...]
And last but not least, a grid-like pattern used to categorize the playlists by Genre and Mood, constructed by using the combination of
[...] <ons-row class="category"> <ons-col modifier="nodivider" id="Category_1" onclick="openPlaylist(this.id)"> <div class="category_wrapper"> <figure class="category_thumbnail"> <ons-icon icon="fa-users"></ons-icon> <div class="category_title" id="Category_1_name">Party</div> </figure> </div> </ons-col> [...] </ons-row> [...]
After tapping on some of the recommended playlists or Genres/Moods, the Playlist Page is opened. Notice that the items in the vertical list won’t activate anything upon tapping them since this would lead to a screen with similar content, but a different organization of the playlist.
For the detail code of this page, including the CSS classes, visit our tutorial page.
The Playlist Page consists of two parts. The first one consists of a carousel showing details about the playlist at the top:
[...] <ons-carousel class="carousel" swipeable auto-scroll id="carousel"> <ons-carousel-item> <div> <figure class="playlist_thumbnail"> <img src="assets/img/profile-image-05.png"> <div class="playlist_title" id="playlist_title">Classical</div> </figure> <div> <div class="playlist_follow">FOLLOW</div> </div> <div class="playlist_info">1,023 FOLLOWERS・BY UNKNOWN AUTHOR</div> </div> </ons-carousel-item> [...] </ons-carousel> [...]
The carousel has two pages (items), the first one presenting the cover of the playlist, the name, number of followers and author, while the second one displays a small description about the playlist as well as the date of upload, and the total duration of the playlist.
The second part consists of the list of the playlist’s tracks, where the first element of the list is an option allowing for the playlist to be played in offline mode:
[...] <ons-list class="track_list"> <ons-list-item class="track_offline"> <div class="center">Available Offline</div> <div class="right"> <ons-switch></ons-switch> </div> </ons-list-item> <ons-list-item class="track" tappable> <div class="center"> <div class="list-item__title">Track 01</div> <div class="list-item__subtitle track_title">Unknown Artist - Track 01</div> </div> <div class="right"> <ons-icon icon="ion-ios-more,material:ion-android-more-vertical"></ons-icon> </div> </ons-list-item> [...] </ons-list> [...]
What’s peculiar about the list’s elements is that each track element has a three dotted icon on the right, which appears horizontally in the case of iOS or vertically in the case of Android. This is accomplished by providing the name of the icon, that will appear on Android, with the
material keyword after the name of the default icon.
Moreover, the two parts are separated by the “Shuffle Play!”
which, when tapped, shows the
element at the bottom of the screen, showing the currently playing track:
[...] <ons-toast> <div onclick="openPlayScreen()"><ons-icon size="20px" icon="angle-up"></ons-icon> Unknown Artist - Track 01 </div> <button><ons-icon id="play_icon" size="20px" icon="play-circle-o" onclick="play_toggle(this.id)"></ons-icon></button> </ons-toast> [...]
By tapping this
element, the Play Screen will open.
This screen is rather simple, however, it contains some interesting components that make its creation quite easy:
[...] <div> <!-- Image --> </div> <ons-row> <!-- Track info --> </ons-row> <ons-row> <!-- Duration info --> </ons-row> <ons-row> <!-- Buttons --> </ons-row> [...]
Apart from the
, this screen consists of one standard
wrapper elements for easily structuring the screen. These elements are used to show the title of the track, the duration as well as the current progress of the playing track and buttons usually found in a music player. Each
is divided into equal width parts by using as many
elements as the number of parts you need.
Although this screen is simple, it can be further improved by enclosing the image and the first
into a carousel, thus enabling songs switching by swiping the carousel.
We hope this little pattern of ours will give you an inspiration about how to design your app. But this is not all! We created several patterns based on popular apps like this one, which can be accessed on our tutorial page and hope that they will be of help to you!
Stay tuned to Onsen UI for even more fun content and new updates!
Onsen UI is an open source library used to create the user interface of hybrid apps. You can find more information on our GitHub page. If you like Onsen UI, please don’t forget to give us a star! ★★★★★
By Adrian Matei
This blog post presents a simple example showing how to insert a document in mongodb, in the Java language.
The code examples are taken from the Free-Programming-Books-Importer, available on Github
Add the java mongo driver to your class path, or if you use maven to the
dependencies in your pom file:
<dependencies> <dependency> <groupId>org.mongodb</groupId> <artifactId>mongodb-driver</artifactId> <version>3.2.2</version> </dependency> ...... </dependencies>
MongoClientURI connectionString = new MongoClientURI("mongodb://codingpedia:codingpedia@localhost:27017/codingpedia-bookmarks"); MongoClient mongoClient = new MongoClient(connectionString);