Monday, May 13, 2013

Making RequireJS and AngularJS Play Together

If you have to make AngularJS and RequireJS play together, here's how to do it.

1. Make Angular wait until you're ready.

  • Remove the ng-app from your HTML. This way, Angular won't run before Require has gathered dependencies.
  • In your main JavaScript file for Require, start Angular manually:
require([], function(){
  
  //... snip ...

  //start angular after dependencies are gathered
  //I'm using document here, but it should be whatever element 
  //you'd put the ng-app on normally
  angular.bootstrap(document, ["moduleWithControllers"]); 
});

2. Put your RequireJS stuff into an Angular module

  • This lets you stay Angular-y from inside Angular code!
  • This should also be in the main .js file for your Require stuff, before running bootstrap()
require(['someDependency'], function(someDependency){
  
  angular.module('requireStuff')
    .factory('someDependency', function(){
      //make this require object or whatever available to angular
      return someDependency;
    });

  //from section #1
  angular.bootstrap(document, ["moduleWithControllers"]); 
});

Then from the Angular code:
angular.module('moduleWithControllers', ['requireStuff'])
  .controller('MyCtrl', function($scope, someDependency){
    //do something with someDependency
  });

3. Get Angular libraries into your Require modules (Optional)

  • This lets you access libraries provided by Angular from outside of Angular code.
  • Warning: These won't be available until after Angular runs the first time, after all Require dependencies are gathered
define([], function(){
  var result = {
    $http: null,
    $q: null
  };

  angular.module('requireLibStuff')
    .service('randomService', function($q, $http){
      result.$http = $http;
      result.$q = $q;
    });

  return result;
});
Then you just need to reference the service from your angular code:
angular.module('main', ['requireLibStuff'])
  .controller('MyCtrl', function(randomService){
    //randomService won't be used, it's only referenced here 
    //to make Angular run the code above
  });

Update

I forgot to mention something for step #3 above: most Angular-provided libraries only work if called within Angular code. For example, the $q.defer() object will only notify its listeners if resolve/reject are called from within the regular Angular $apply and the like.

Wednesday, January 9, 2013

Check All Bookmarklet

Here's a bookmarklet for checking or un-checking all check boxes on a web page. It will flip the first check box, then set all the others accordingly.

check!

Here are a couple checkboxes, just to try it:
Here's the code, de-minified:
(function(){
 //all inputs on the page
 var cbs=document.getElementsByTagName('input'); 
 //the value for the checked (true of false)
 var cv;
 //the current checkbox
 var cb;
 
 for(var i in cbs){
  cb=cbs[i];
  if(cb.type=='checkbox'){
   if(cv==null)
    cv = !(cb.checked);
   
   cb.checked=cv;
  }
 }
 
 void(0); //prevent the bookmarklet from switching pages
})() //call the anonymous function


To get this bookmarklet, just drag it to your bookmarks toolbar or your bookmarks area. Click it whenever you want to use it.

Arduino - HSV to RGB

I got an Arduino for Christmas, along with a cool starter pack that contains all kinds of cool switches, LEDs, wires, etc. My favorite component to play with so far is the RGB LED. It has red, green, and blue LEDs inside of one unit, so you can use it to fake any color.

I started with making it just show random colors, but then thought I could do better. The code below chooses a random Saturation and Hue, then turns the brightness all the way up, all the way down, and then starts over again.

//these have to be attached to PWM pins
int REDPin = 6;
int GREENPin = 5;
int BLUEPin = 3;


int vIncrement = 5;

unsigned int h = 0, s = 0, v = 0; //hsv
unsigned int r, g, b, hh, c, x, m;


void setup()
{
  pinMode(REDPin, OUTPUT);
  pinMode(GREENPin, OUTPUT);
  pinMode(BLUEPin, OUTPUT);
  randomSeed(analogRead(0));
  Serial.begin(9600);
}

void loop()
{
  v = v + vIncrement;

  if (v <= 0){
    h = random(0, 360);
    hh = h / 60;
    s = random(0, 255);
  }
  
  if (v <= 0 || v >= 255)    // reverse the direction of the fading
  {
    if (v > 0x10000) //handle overflow - unsigned int
      v = 0;
    vIncrement = -vIncrement;
    v = constrain(v, 0, 255);
  }
  
  c = (v * s) / 256;
  x = (c * (60 - abs(h % 120 - 60))) / 60;
  m = v - c; // 44
  
  switch(hh){
    case 0:
      r = c + m;
      g = x + m;
      b = m;
      break;
    case 1:
      r = x + m;
      g = c + m;
      b = m;
      break;
    case 2:
      r = m;
      g = c + m;
      b = x + m;
      break;
    case 3:
      r = m;
      g = x + m;
      b = c + m;
      break;
    case 4:
      r = x + m;
      g = m;
      b = c + m;
      break;
    case 5:
      r = c + m;
      g = m;
      b = x + m;
      break;
    default:
      r=g=b=m;
  }
  
  
  r = constrain(r, 0, 255);
  g = constrain(g, 0, 255);
  b = constrain(b, 0, 255);
  analogWrite(REDPin, r);
  analogWrite(GREENPin, g);
  analogWrite(BLUEPin, b);

  delay(20);  // wait for 20 milliseconds to see the dimming effect
}

There are lots of algorithms out there for converting HSV to RGB, but I didn't like all the converting between float and int. This one does it only using unsigned ints (my Arduino uses 16-bit numbers, so I needed them unsigned to prevent overflow). It was based on the Wikipedia HSV page.

(For this algorithm, S, V, R, G, B are in [0, 255] and H is in [0, 360])

Tuesday, October 25, 2011

Lego Creeper

It ended up a little short, but was made from enough bricks to fill the $15 container at the Lego store.

Friday, August 20, 2010

Blog!

This is a blog entry.

Saturday, February 27, 2010

Software Design Lessons for Business People

At work recently, a client requested a huge, complicated (but really cool) feature. Because it was such a cool feature, I slightly underestimated in hopes that the client would approve it. When they found out about the estimate, the client was surprised it was so high - I think they even called it "absurd!" They thought the (huge, complicated) feature would take no more than 2 hours.

This isn't the first time something like this has happened. Most business people seem to think that the hard part of software development is thinking of how a feature should work. In other words, "I can think of how it works, so programming it must be easy!"

So, business people, here's a good way to think of software development. Imagine that you have a worker who only speaks Italian. You have a simple task that you want him to do. However, this particular worker does exactly what you tell him, only what you tell him, and all of what you tell him. So you have to come up with exact instructions, translate them into Italian, watch him try to perform the action, then alter the original instructions if things don't go the right way. How many times would you have to let him go through the procedure before you got it right? How many provisions would you have to create for unusual situations?

Now take that employee and make it a computer. That's software development! We have to translate requirements into exact instructions that the computer understands. Coming up with the requirements is important, but it's just the first step of a long process.

Thursday, August 6, 2009

Real Life! AHHHHH!!!!!!!

With graduation came the realization that I'm now doing what I will be doing for the rest of my life. And I want writing on this Blog to be a part of it. So I'm now planning to do more posts, and make them more meaningful.

This Blog started out as a school project, so I didn't really get a choice about what topics I could write about. Now I get to decide what to make this blog about. After that class was over, I scrambled to post, wanting to make this a great blog. I still didn't really have the time to think about a theme for my blog, though. I'm still thinking about that, but I have some pretty good ideas so far:
  • Life
  • General Geekiness (video games, hacks, TV, books...)
  • Advanced Geekiness (programming, Internet, Linux, software companies, math...)
  • Music
  • Random stuff that interests me

I'm aiming for a post about twice a month, with at least one of those being geeky. That's starting in August, with this post not counting!