Android Studio was unable to find a valid Jvm on MAC #Solved

If you have installed Android Studio on your MAC, you may run into an error that says “Android Studio was unable to find a valid Jvm” when you try to open this up. After a little work I was able to get it fixed and here is how I did it.

The problem:
/Applications/Android Studio.app/Contents/Info.plist has a setting in there that is looking for JDK 1.6*. Any good computer user will update their java as they need to so chances are that you will have 1.7 or even 1.8.

The solution:
We just have to tell Info.plist to look for your version instead of 1.6

The steps:

    1. Go here and check which java version that you have – https://www.java.com/en/download/installed.jsp.
      1. Mine was 1.8
    2. Edit /Applications/Android Studio.app/Contents/Info.plist
      1. May live somewhere else on your machine
    3. Change
      1. <key>JVMVersion</key>
        <string>1.6*</string>
    4. to
      1. <key>JVMVersion</key>
        <string>1.(7 or 8)*</string>
    5. Save and exit

That fixed me right up and I was able to start working in the tool.

Hope it helps.

Advertisements
Tagged ,

Using LocalStorage for client side caching

I have a need to get a list of all production devices and place them on a map. This data takes about 12 – 16 seconds to load. This means that if a user wants to view the map on page load they are out of luck for a few seconds. So what I do is allow the wait to happen once and then cache the data in local storage. This data is updated every 5 minutes. This allows the user to have at least the last fetch of data locally and will display a map right away.

Here is my angular service for doing this:

//Angular service that gets a list of devices
dashboardApp.service('deviceService', function() {
    //Set self to this so we dont lose scope
    var self = this;
    self.devices = new Array();
    //Go and get the latest device list - Takes a long time!!!!
    this.promise = $.getJSON('devicelist');
    //Since the last call takes a long time, I toss it in local storage and grab the cached version from there until the new list comes in.
    if (localStorage.getItem(&amp;quot;devicelist&amp;quot;)) {
        //I store json as text and need to parse it to make it a JS object
        self.devices = JSON.parse(localStorage.getItem(&amp;quot;devicelist&amp;quot;));
    }
    //When the promise (ajax call) is comeplte then write the data to local storage for next time and set the var to the new list
    $.when(this.promise).then(function(data) {
        self.devices = data;
        localStorage.setItem(&amp;quot;devicelist&amp;quot;, JSON.stringify(data));
    });
    //Repeat every 5 minutes.
    setInterval(function() {
        $.getJSON('devicelist', function(data) {
            self.devices = data;
            localStorage.setItem(&amp;quot;devicelist&amp;quot;, JSON.stringify(data));
        });
    }, 300000)
});
Tagged , , ,

Angular try to avoid $scope.$apply() inprog error

Sometimes Angular does not pick up deep variable changes and needs a kick to do so. We have $scope.$apply() available to use but sometimes it is running already and you get an error when using it. Here is what I found from here and it works.

My Modified Version:

if(!$scope.$$phase) {
 $scope.$apply();
 }
Tagged ,

Polling VS Websockets – 1 Thing to consider

In a meeting today, A Co-Worker mentioned that Basecamp uses polling vs websockets because of stability. I mentioned that I might be converting one of my websockets to polling because it goes down sometimes.

Here is what I learned:

If your server fails for whatever reason the websocket will die and you will have to restart the connection. Now, this isn’t that bad as long as your program never crashes but if there is an intermittent db connection problem or some other unhandled error, the socket will fail and you will need a client side watcher to get it going again.

Polling works in this situation because what is down now may be up in 30 seconds and it will just keep polling even if the last one failed.

Here is a polling example:

 

self.poll = function() {
setTimeout(function() {
$.ajax({
url: "MY_URL",
success: function(data) {
self.alerts = data;
},
dataType: "json",
complete: function (){ self.poll(); }
});
}, 15000);
}

BTW: Using an angular service vs writing this code in multiple controllers made the conversion take less than 5 minutes.

Tagged , , ,

Replace confirm with Bootstrap modal and Backbone view

We all hate ugly confirms but now you can use a nice backbone view and bootstrap modal to bug your users and act on btn click.

Modal:

<div class="modal fade" id="confirm-modal">
 <div class="modal-dialog">
 <div class="modal-content">
 <div class="modal-header">
 <span id="header-text"></span><button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
 <h4 class="modal-title">Are You Sure?</h4>
 </div>
 <div class="modal-body">
 </div>
 <div class="modal-footer">
 <button type="button" class="btn btn-default" data-dismiss="modal">Close</button> <button type="button" class="btn btn-primary btn-ok" data-dismiss="modal">OK</button>
 </div>
 </div><!-- /.modal-content -->
 </div><!-- /.modal-dialog -->
</div><!-- /.modal -->

Backbone View:

App.Views.ConfirmModalClass = Backbone.View.extend({
   el: "#confirm-modal",
   events: {
    "click .btn-ok": "runCallBack"
   },
   initialize: function(args){
	   this.$el.find(".modal-body").html("<p>"+args.body+"</p>");
	   this.cb = args.cb;
   },
   render: function(){
     this.$el.modal("show");
  },
  close: function(){
     this.$el.modal("close");
  },
  runCallBack: function(){
       this.cb();
  }
});

Usage (from inside another view):

var that = this;
	   var confirmModal = new App.Views.ConfirmModalClass({
	      cb: function(){
				//use that to run functions for this view
	      },
		  body: "BODY"
	   });
	    confirmModal.render();
Tagged , ,

Capture Current Location inside of a Backbone Model

Here is how I take the lat and lng from the browser and turn it into a Backbone Model with a function to figure out haversine

var CurrentLocationModel = Backbone.Model.extend({
   initialize: function(){
    this.getLocation();
  },
  getLocation: function(){
        var that = this;
		if (navigator.geolocation){	
			navigator.geolocation.getCurrentPosition(function(position){
				that.set("lat",position.coords.latitude);
				that.set("lng",position.coords.longitude);
			});
		}else{
		    that.set("lat",0);
			that.set("lng",0);
		}
   },
   getDistance: function(lat,lng){
        //see http://stackoverflow.com/questions/14560999/using-the-haversine-formula-in-javascript
		var that = this;
		var R = 6371; // km 
		console.log(that.get("lat"));
		//has a problem with the .toRad() method below.
		var x1 = that.get("lat")-lat;
		var dLat = x1.toRad();  
		var x2 = that.get("lng")-lng;
		var dLon = x2.toRad();  
		var a = Math.sin(dLat/2) * Math.sin(dLat/2) + 
					Math.cos(lat.toRad()) * Math.cos(that.get("lat").toRad()) * 
					Math.sin(dLon/2) * Math.sin(dLon/2);  
		var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); 
		var dist = R * c;
        return(dist);		
   }
  
});
Tagged , ,

Use Backbone (Underscore) templates with Mojolicious

Mojolicious uses it’s own embeded Perl parser and the embeded variables look something like this:

<%= $var %>

Underscore uses this as their embeded vars:

<%= var %>

So unless we use a different template engine, we cannot place these underscore templates inline with mojolicious templates because it will try to parse the Javascript template.

Here is how I get around it:

1. Create the template as a plain html file.
A.The file name of this template will be user.html:

<%= first_name %> <%= last_name %> 

2. Place the html file inside of your public directory in the mojo tree.

3. Create a javascript function that does grabs the template when you need it:

window.template = function(id){
    var theTemplate = ""

    $.ajax({
	url:"/templates/"+id+".html",
	success: function(data){
	  theTemplate = data;
    },
	async: false
	});

return _.template(theTemplate); 

};

5. Implement the template in a view

App.Views.User = Backbone.View.extend({
   el: "#main",
   render: function(){
    var theTemplate = template("user");	
    this.$el.html(theTemplate(this.model.toJSON()));
  }
});

6. run the render function when needed.

That is all it took and it works great.

Tagged , , , , ,