Here's a solution someone posted: http://jsfiddle.net/rur_d/tNZAm/
Some say it's bad idea to have your controllers being aware of classes. Well it's a solution that works.
My online tech scrapbook where I keep my notes in case I need to look them up later
Saturday, July 21, 2012
Document Ready Event When Using AngularJS With JQuery
When you are making a page out of multiple partials/fragments in AngularJS, the document ready event for JQuery seems to fire before the page is fully assembled.
The correct way to do something when the page is fully loaded in AngularJS is by using the '$viewContentLoaded' event listener, by putting the following code into your controller.
Reference: http://www.aleaiactaest.ch/angular-js-and-dom-readyness-for-jquery/
The correct way to do something when the page is fully loaded in AngularJS is by using the '$viewContentLoaded' event listener, by putting the following code into your controller.
| $scope.$on('$viewContentLoaded', function(){ // do something }); |
Reference: http://www.aleaiactaest.ch/angular-js-and-dom-readyness-for-jquery/
AngularJS: Calling a Javascript Function in the Controller
This is done by using "ng-click".
Example assuming you already created a function in the controller called "doSomething":
Example assuming you already created a function in the controller called "doSomething":
| <a href ng-click="doSomething()">Do It</a> |
Friday, July 20, 2012
Jersey Exception Handling
Jersey offers centralized Exception handling with "ExceptionMappers". This means you can allow Exceptions to be thrown up to the framework and then you can define how to handle them. It also means you are able to "catch" and handle exceptions that occur before and after the code that you write is being run.
Let's say you want to handle "MyWebServiceException", you can create an ExceptionMapper "MyWebServiceExceptionMapper" like this:
In order for this to be registered with Jersey, you'll need to put it in a package that's being scanned by Jersey to be resources or providers, so in the web.xml, have something like this:
In this example, I separated the packages for resources and providers, providing 2 packages to be scanned.
To handle each exception differently, just create as many ExceptionMapper classes as you wish, and put them in the same package to be picked up and registered.
You can also use this to return a different HTTP status code for different errors, but as mentioned in the comments of an earlier POST, that's not going to work well with cross-domain Javascript REST requests.
Let's say you want to handle "MyWebServiceException", you can create an ExceptionMapper "MyWebServiceExceptionMapper" like this:
| @Provider public class MyWebServiceExceptionMapper implements ExceptionMapper<MyWebServiceException> { @Override public Response toResponse(Exception e) { GenericEntity<String> entity = new GenericEntity<String>( “{\"statusCode\":\"ERR-100\",\"responseData\":\"Error Processing Web Service\"}” ){}; return Response.status(Status.OK).entity(entity).type(MediaType.APPLICATION_JSON).build(); } } |
In order for this to be registered with Jersey, you'll need to put it in a package that's being scanned by Jersey to be resources or providers, so in the web.xml, have something like this:
| <init-param> <param-name>com.sun.jersey.config.property.packages</param-name> <param-value>com.myws.resource;com.myws.provider</param-value> </init-param> |
In this example, I separated the packages for resources and providers, providing 2 packages to be scanned.
To handle each exception differently, just create as many ExceptionMapper classes as you wish, and put them in the same package to be picked up and registered.
You can also use this to return a different HTTP status code for different errors, but as mentioned in the comments of an earlier POST, that's not going to work well with cross-domain Javascript REST requests.
Thursday, July 19, 2012
Jackson Polymorphism
You can handle polymorphism with Jackson using the following annotations at the class level:
This will tell Jackson to map the object to the "AdminAccount" class when the "accountType" property is "ADM", and to the "NormalAccount" class when the "accountType" property is "NML".
Other options are available, such as directly using the class name.
One "gotcha" I discovered is that the "accountType" property must not be implemented in the POJO class. If there is an "accountType" property in the class, it will be null when it's time to work with it in Java. In Java-land, you'll have to use "instanceof" to know what object it is.
A article with more detailed examples: http://programmerbruce.blogspot.com/2011/05/deserialize-json-with-jackson-into.html
| j@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "accountType") @JsonSubTypes({ @Type(value = AdminAccount.class, name =”ADM”), @Type(value = NormalAccount.class, name =”NML”) }) |
This will tell Jackson to map the object to the "AdminAccount" class when the "accountType" property is "ADM", and to the "NormalAccount" class when the "accountType" property is "NML".
Other options are available, such as directly using the class name.
One "gotcha" I discovered is that the "accountType" property must not be implemented in the POJO class. If there is an "accountType" property in the class, it will be null when it's time to work with it in Java. In Java-land, you'll have to use "instanceof" to know what object it is.
A article with more detailed examples: http://programmerbruce.blogspot.com/2011/05/deserialize-json-with-jackson-into.html
Wednesday, July 18, 2012
HTTP Status Codes for REST
For REST services, one common pattern is to use HTTP status codes as the status code for the request itself.
A good reference: http://restpatterns.org/HTTP_Status_Codes
A good reference: http://restpatterns.org/HTTP_Status_Codes
ProGuard: Read Obfuscated Stack Traces
You'll need to run retrace.jar.
You'll also need proguard.jar in the same folder.
Link: http://proguard.sourceforge.net/index.html#manual/retrace/examples.html
| java -jar retrace.jar proguard.map stacktrace.txt |
Link: http://proguard.sourceforge.net/index.html#manual/retrace/examples.html
Sunday, July 15, 2012
iOS: AudioQueue Get Audio Level
A very good example of this is found in the "SpeakHere" reference project provided by Apple:
Link: http://developer.apple.com/library/ios/#samplecode/SpeakHere/Introduction/Intro.html
Just some gotcha's and points to note:
You need to call AudioQueueSetProperty to enable the level metering feature in the first place:
The number returned by the AudioQueue will be a negative number with a maximum value of 0. To convert it to a number on a linear scale (i.e. gain level), use the following formula:
Where averagePower is the value returned by the AudioQueue for the audio level average power.
The rest should be pretty straight-forward from studying the example.
Links and References:
Link: http://developer.apple.com/library/ios/#samplecode/SpeakHere/Introduction/Intro.html
Just some gotcha's and points to note:
You need to call AudioQueueSetProperty to enable the level metering feature in the first place:
| UInt32 enableMetering = 1; AudioQueueSetProperty(audioQueue, kAudioQueueProperty_EnableLevelMetering, &enableMetering, sizeof(UInt32)); |
The number returned by the AudioQueue will be a negative number with a maximum value of 0. To convert it to a number on a linear scale (i.e. gain level), use the following formula:
| float level = pow(10., 0.05 * averagePower); |
Where averagePower is the value returned by the AudioQueue for the audio level average power.
The rest should be pretty straight-forward from studying the example.
Links and References:
- http://stackoverflow.com/questions/1149092/how-do-i-attenuate-a-wav-file-by-a-given-decibel-value
- http://stackoverflow.com/questions/1281494/how-to-obtain-accurate-decibel-leve-with-cocoa
- http://stackoverflow.com/questions/9403094/ios-audioqueue-kaudioqueueerr-invalidpropertyvalue-for-property-kaudioqueueprop
Mongo DB: Java API Get Object by ID
You'll get an error if you try to do something along the lines of "{_id: xxxxx}".
This is how it's done:
This is how it's done:
| BasicDBObject searchCriteria = new BasicDBObject("_id", new ObjectId(id)); DBObject dbObj = collection.findOne(searchCriteria); |
Jackson: Ignore Unrecognized Fields
By default, Jackson will throw an exception when a field in the JSON is not declared as a member variable in the class it is mapped to.
To ignore these fields, add the following annotation to the POJO class:
| @JsonIgnoreProperties(ignoreUnknown=true) |
AngularJS: Batarang Debugging Tool
Recently, a debugging tool call Batarang was released for AngularJS. It runs as a Google Chrome extension.
Here's a blog about it:
http://blog.angularjs.org/2012/07/introducing-angularjs-batarang.html
Installation instructions:
https://github.com/angular/angularjs-batarang/blob/master/README.md
Things to note:
Here's a blog about it:
http://blog.angularjs.org/2012/07/introducing-angularjs-batarang.html
Installation instructions:
https://github.com/angular/angularjs-batarang/blob/master/README.md
Things to note:
- It doesn't run on the stock Google Chrome. It runs on the "Canary" version which has experimental features for early adopters. You'll have to download, install, and run it as a separate program.
- Installing the extension the usual way won't work due to security restrictions. You'll have to drag the "crx" file into the extensions page (i.e. chrome://chrome/extensions/).
iOS: Making the Table Cell Background a Gradient
This is a good guide for doing it:
http://www.raywenderlich.com/2033/core-graphics-101-lines-rectangles-and-gradients
http://www.raywenderlich.com/2033/core-graphics-101-lines-rectangles-and-gradients
GUID Uniqueness
This is an article explaining how GUID can be almost certainly (if not totally certainly unique).
Link: http://blogs.msdn.com/b/oldnewthing/archive/2008/06/27/8659071.aspx
This is done by including the following information in the GUID:
Link: http://blogs.msdn.com/b/oldnewthing/archive/2008/06/27/8659071.aspx
This is done by including the following information in the GUID:
- Machine ID (network card Mac address)
- Timestamp
- Counter to differentiate entries generated within the same timestamp
- Algorithm version identifier
MongoDB: Scaling Approach
The first step in scaling is creating Replica sets (master/slave) where the slaves are allowed to service queries. This will be helpful for read-mostly workloads.
After that, the next step is sharding, where you'll need to define a partitioning mechanism. At a very large scale, the topology would be that of multiple shards, within which contain individual replica sets.
Link: http://www.mongodb.org/display/DOCS/Sharding+Introduction
After that, the next step is sharding, where you'll need to define a partitioning mechanism. At a very large scale, the topology would be that of multiple shards, within which contain individual replica sets.
Link: http://www.mongodb.org/display/DOCS/Sharding+Introduction
Mongo DB Object ID
It is the unique identifier for each document in a collection. Compared to UUID, it is smaller (12 vs 16 bytes) but should still be workable because the requirement is just to have uniqueness within the DB cluster.
Uniqueness is guaranteed by including the machine ID, process ID, a timestamp and a counter for entries generated within the same second.
Link: http://www.mongodb.org/display/DOCS/Object+IDs
Uniqueness is guaranteed by including the machine ID, process ID, a timestamp and a counter for entries generated within the same second.
Link: http://www.mongodb.org/display/DOCS/Object+IDs
Saturday, July 14, 2012
Git: Conflict Resolution By Choosing A Copy
Often, it is as simple as choosing either the local copy in its entirety or the remote copy in its entirety.
In this case, use the following commands:
In this case, use the following commands:
- Use local copy: git checkout --ours FILENAME
- Use remote copy: git checkout --theirs FILENAME
Thursday, July 12, 2012
iOS Activity Indicator
This is how it is done (example is using WebView)
Link: http://stackoverflow.com/questions/11334247/add-activity-indicator-to-web-view
I made some further changes so the indicator is more visible (by putting it inside an alert popup):
Note that I set the frame after "show". This is because if I wanted to calculate x,y,w,h relative to the size of the loading alert frame, these values will only be non-zero after show.
Link: http://stackoverflow.com/questions/11334247/add-activity-indicator-to-web-view
I made some further changes so the indicator is more visible (by putting it inside an alert popup):
| - (void)viewDidLoad { [super viewDidLoad]; loadingAlert = [[UIAlertView alloc] initWithTitle:@"Loading..." message:@"\n" delegate:self cancelButtonTitle:nil otherButtonTitles:nil, nil]; activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite]; [loadingAlert addSubview:activityIndicator]; } - (void) showLoadingAlert { [loadingAlert show]; activityIndicator.frame = CGRectMake((x,y,w,h); [activityIndicator startAnimating]; } - (void) dismissLoadingAlert { [activityIndicator stopAnimating]; [loadingAlert dismissWithClickedButtonIndex:0 animated:NO]; } |
Note that I set the frame after "show". This is because if I wanted to calculate x,y,w,h relative to the size of the loading alert frame, these values will only be non-zero after show.
NSTimer Gotchas With Threads/RunLoops
Sometimes when you notice that the NSTimer isn't working (i.e. the scheduled task doesn't fire), it can be caused by runloop issues.
By default, it runs in the current run loop from where it is scheduled. If you schedule it from the wrong loop, it might not fire as the loop could be blocked somewhere else.
Which method you use to initialize the timer also makes a difference. The "scheduledTimerWithTimeInterval" creates a timer that runs in the current loop. If the current loop is not suitable for the timer to run, the timer may not fire and you have no idea why.
If you have a problem with the above, you will have to use the "timerWithTimeInterval" methods. However, you have to remember to add the timer to the run loop that you want to add on.
For example, to schedule a timer on the main loop from another loop:
The various behaviors are documented in the class reference.
Reference: https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/nstimer_Class/Reference/NSTimer.html
By default, it runs in the current run loop from where it is scheduled. If you schedule it from the wrong loop, it might not fire as the loop could be blocked somewhere else.
Which method you use to initialize the timer also makes a difference. The "scheduledTimerWithTimeInterval" creates a timer that runs in the current loop. If the current loop is not suitable for the timer to run, the timer may not fire and you have no idea why.
If you have a problem with the above, you will have to use the "timerWithTimeInterval" methods. However, you have to remember to add the timer to the run loop that you want to add on.
For example, to schedule a timer on the main loop from another loop:
| NSTimer *timer = [NSTimer timerWithTimeInterval:waiTime target:self selector:@selector(fireMethod:) userInfo:nil repeats:YES]; [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes] |
The various behaviors are documented in the class reference.
Reference: https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/nstimer_Class/Reference/NSTimer.html
Wednesday, July 11, 2012
iOS: Positioning a View Relative to Parent
This is done via the "frame" property of the View, e.g.
| viewObj.frame = CGRectMake(20,20,50,40); |
Tuesday, July 10, 2012
MySQL: Dumping With Users and Privileges
A gotcha when trying to clone an entire MySQL DB is that the user privileges are not completely cloned.
The following command would have resulted in users and privileges being cloned (since the "mysql" database would have been dumped), but they do not take effect until a "FLUSH PRIVILEGES" command has been issued:
This means additional manual step of issuing the "FLUSH PRIVILEGES" command is needed before the DB is usable.
In order to ensure that the "FLUSH PRIVILEGES" command is run during DB restore (so no additional steps needed to get DB up and running), include the "--flush-privileges" option during the dump.
The following command would have resulted in users and privileges being cloned (since the "mysql" database would have been dumped), but they do not take effect until a "FLUSH PRIVILEGES" command has been issued:
| mysqldump --all-databases > db.sql |
This means additional manual step of issuing the "FLUSH PRIVILEGES" command is needed before the DB is usable.
In order to ensure that the "FLUSH PRIVILEGES" command is run during DB restore (so no additional steps needed to get DB up and running), include the "--flush-privileges" option during the dump.
| mysqldump --all-databases --flush-privileges > db.sql |
Subscribe to:
Posts (Atom)