I’ve spent the last couple of hours battling Grunt config to use Angular and Jasmine testing framework with Yeoman’s (yo) chromeapp a.k.a generator-chromeapp. Here’s how I did it:
- Run yo chromeapp with the test-framework option
yo chromeapp --test-framework=jasmine
- Install Angular dependencies using bower
bower install --save angular
bower install --save-dev angular-mocks
bower install --save angular-animate
bower install --save angular-material #Optional
If you plan to use bower, note that the generator puts the bower_components directory in the app folder. You can modify this by changing the “directory” in .bowerrc. I’ve chosen to keep it as-is
- Create app.js in app/scripts and define your module
angular.module('MyChromeApp', ['ngAnimate', 'ngMaterial']);
- Modify your index.html
<html ng-app = "MyChromeApp">
<!-- Optional -->
- Modify the jasmine task in Gruntfile.js
- You’re done! Now you can create controllers and services using
yo angular:controller Dashboard
yo angular:service Storage
- Run jasmine for unit-testing
I’m working on an Angular-based Chrome app at the moment and I needed to make a search box. The search filter example in the Angular docs shows how to search based on a single property of the array objects. It also shows the use of multiple input boxes to search in different properties.
The example data has “Julie 555-8765” and “Juliette 555-5678”. Wouldn’t it be nice if the search field could handle queries like “julie 555” and show both of them as search results?
In essence, the search filter would need to match “555” in the “phone” property and “julie” in the “name” property. It would have to break down the search query into parts (“555” and “julie”), make sure that each part matches one of the properties of the object and show it in the results only if all parts are found in the object. This can be done by combining the multiple properties of the object into a single string, checking if each query part is found as a substring of the object string, and doing an AND operation of the results of all query parts.
Here’s some sample code
A Plunker version of the same code is available here
Go ahead and type something like “555” and you’ll see two results, Jane Doe and Jane Smith. If you change that to “555 Doe”, the Jane Smith result is dropped.
Note that the filter function is rather intensive because it converts each object to a JSON string and tries to locate all query string parts in it. To prevent frequent execution of the filter function, this makes use of the relatively new ng-model-options (added in Angular 1.3) to delay the ng-model update by 400 milliseconds. You may want to tweak the delay amount.
I was trying to access a Postgres database on my WebFaction server using the PostgreSQL admin tool PgAdmin III. It took a little bit of Googling to figure it out, so here’s a quick guide for anyone in similar situations.
If your hosting provider, like mine, does not allow direct remote access to databases, you need to create an SSH tunnel so that accessing the default Postgres port, 5432, on your computer redirects to port 5432 on the server. For WebFaction accounts, that can be done like this
ssh -L 5432:127.0.0.1:5432 accountname@webXX.webfaction.com
where webXX refers to your WebFaction server.
If you see “bind: Address already in use”, it means that the postgresql service running on your computer on port 5432 is preventing the SSH tunnel from being set up on the same port. To stop your local postgresql service, on Ubuntu, you can do this
sudo service postgresql stop
When the postgresql service has stopped, you can set up the SSH tunnel.
Use the “Add server” option and provide the following configuration
- Host: 127.0.0.1
- Port: 5432
- Username: <remote Postgres username>
- Password: <remote Postgres password>
- Maintenance DB (only if you have trouble connecting to your server): <remote Postgres database name>
One of the reasons why working at a startup excites me is the unpredictability of my future tasks. Case in point: I was recently asked to set up a mail server as a replacement for the Google Apps subscription currently in use. The requirements given to me specified that IMAP support and a web client are essential, as is the ability to send out emails not just to internal addresses, but also to other domains. After all, what good is a mail server if it can’t talk to the rest of the world? I decided to get started, but there was a tiny hold-up: I had no idea how to build a mail server! Continue reading →
As requested by a reader, here’s a simple tutorial explaining the use of menu items in an ActionBar. Menu items shown in the ActionBar are called “action items”, and they’re just as easy to use as menu items. This demo app shows an appropriate Toast when action items are selected.
To start with, make sure to set the minimum SDK version as 11 (Android 3.0 Honeycomb) or greater. ActionBar was introduced in Honeycomb, and will not work on platform versions below that without the help of the Android support library and/or ActionBarSherlock (Setting up ActionBarSherlock is covered here).
Continue reading →
AlertDialog is a handy subclass of Dialog that displays a simple message, typically with “yes” (positive) or “no” (negative) options. However, the Dialog class has been deprecated to make way for DialogFragments. I made a simple class called AlertDialogFragment that implements an AlertDialog within a DialogFragment. Continue reading →
If you’re trying to create a drag-and-drop ListView using the TouchListView (aka cwac-touchlist) library (which essentially refactors the code used by Google in the playlist tab of the Music app), you may encounter an undocumented bug: If two or more items have the same content, say, the same String value, and you attempt to drag and drop them together, the list items will randomly reshuffle and not let that happen. I drove myself crazy trying to find the cause of this bug, but I couldn’t find anything (It’s not often that listViews have the same content repeated in multiple rows, I suppose).
Anyway, to work around the bug, I came up with this silly hack:
StringBuilder builder = new StringBuilder();
word is a String being added to the ListView. To avoid multiple rows having the same value, I’ve had to resort to padding the word with spaces!
This post covers how to use navigation tabs in the ActionBar using ActionBarSherlock. Although the demo in the ActionBarSherlock download shows how to create navigation tabs, they are not associated with Fragments. I looked around online and could not find any tutorials for it. Now that I’ve figured it out, I thought I’d share it.
This tutorial has two Fragments, FragmentA and FragmentB, each of which has a TextView and a Button in their layouts.
Continue reading →
If you’re like me, you’re probably quite comfortable using Android APIs and making apps. But starting with Honeycomb (Android 3.0), there’s a new UI component called Fragment, and this changes everything. It’s quite annoying that Fragments are only available on 3.0 and upwards, and the market share of these platforms is only 8.2% as of May 1, 2012. Clearly, targetting only Honeycomb and ICS would be silly. Google has tried to work around that issue by releasing a compatibility library meant for applications using Android 1.6 and above, but a lot of the magic in ActionBar and Fragments is lost.
Enter ActionBarSherlock (ABS), an extension of the default compatibility library that works like a charm on Android 2.x versions. Setting up ActionBarSherlock, though, involved a bit of head-scratching for me. I use MOTODEV Studio, but these steps should work on Eclipse as well.
- Download the latest version (4.1.0 at the time of writing) of ActionBarSherlock and extract it
- Create a new Android Project and choose Create project from existing source, and browse to /library in the extracted folder. This will be used as a library project
- To make it a library project, open the Properties of the newly created project and under the Android section, check the “Is Library” option and click Apply.
- At this point, if you have a lot of errors (Fragment cannot be resolved to a type etc), open up Properties again, go into the Java Build Path section, and under the Libraries tab, click on Add External JARs, and browse to library/libs in the extracted folder and select android-support-v4.jar. This should get rid of the errors.
- Now that the library project is ready and error-free, it’s time to try a sample. Create a new Android Project, choose Create project from existing source once again, and select samples/demos in the extracted folder. This is a sample project that demonstrates how to use ABS.
- The library project needs to be associated with this project. To do so, open up the Properties of the Demos project, go to the Android section, and click Add and select the library project (usually com_actionbarsherlock). Click Apply.
- If this project also has a lot of errors, you may need to add android-support-v4.jar as an external JAR for this project. (Follow Step 4)
- Once you’re ready to make your own application, create a new Android project, making sure to set android:targetSDKVersion to the latest SDK (Android 15, 4.0.3 at the time of writing). Of course, com_actionbarsherlock will need to be associated with the new project as a library.