2002 Power Mac G4 Quicksilver from eBay – on it’s way

For no other good reason than “why not” I just picked up a Power Mac G4 800Mhz from eBay for < $100, with OS X 10.4 installed. I’ve been shopping for a G4 MDD for a while, but as the highest spec’d G4 that can still run Mac OS 9 these seem to go for a pretty penny on eBay given their age. I almost picked up an MDD without a HDD for a decent price, but for a working machine with a fresh OS X install this G4 seems a pretty safe bet, so fingers crossed, now waiting for my new toy to arrive.

Samsung Galaxy S8 and the DeX dock

It’s interesting how some tech product features come and go over time. It’s not the first time we’ve had a dockable phone that converts into a desktop replacement while in it’s dock. We’ve had the Motorola Atrix with it’s dual boot Android and Linux WebTop desktop when inserted into its laptop dock or docking cradle. Motorola’s Lapdock also supported a number of other Android phones that had the same capability (include the Droid Bionic, Droid Razr).

More recently, Microsoft’s Lumia 950 with Window Mobile’s Continuum feature tried to bring us the promise of a mobile Windows device that you could dock while not on the go to provide a Windows desktop experience from the same device.

Today’s Samsung Unpacked 2017 event introduced the expected S8 and S8+. It’s an incredibly attractive new flagship device that is most likely going to sell like hotcakes, despite even the disaster that was the Note 7. The curious wildcard feature though is a new feature called DeX that allows you to dock your phone into a docking cradle and use it as a desktop.

Given the lacklustre interest in this capability in previous products so far, what makes Samsung think that this is going to capture our interest now? Or as Engadget asks, “Does anyone want to use a phone as a desktop?”

Deploying a git subtree to Heroku (or other PaaS)

Most of the common PaaS platforms like OpenShift and Heroku deploy code based on a source in a git repo – you push your local repo containing source to the remote repo on the platform, the build is performed remotely and then deploys the built artifacts.

What if you want to deploy an app that is prebuilt, or you have a git repo that contains various subfolders, and only part of the folder structure in the repo is what you need deployed?

I’ve been experimenting with a simple React app that also has a node.js backend. In hindsight restructuring the source tree to make the app easier to deploy may have been simpler, but it turns out you can push part of your source subtree to a remote repo, like an application deployed to Heroku, using ‘git subtree’:

git subtree push –prefix subfoldername heroku master

This is discussed in this post here.

React Flux Store: addChangeListener is not a function

Using React with Flux, you need to register a callback from your Component so that it can be called when the Store emits an event. For an ExampleComponent and ExampleStore, this might look like:

class ExampleComponent extends Component {

    constructor(props) {
        super(props);
    }

    componentWillMount(){
        ChatStore.on('change', this.handleUserNameChange);
    }
...
}

I’ve seen some examples where a helper function is declared in the Store that registers your Component as a listener, so the call from the Component to register with the Store might look like:

    componentWillMount(){
        ChatStore.registerChangeListener(this.handleUserNameChange);
    }

and in your ExampleStore you’ll declare registerChangeListener() (and similar to remove) like this:

addChangeListener(callback) {
    this.on('change', callback);
}

removeChangeListener(callback) {
    this.removeListener('change', callback);
}

All good so far, but here’s the issue I just ran into:

Uncaught TypeError: _ExampleStore2.default.addChangeListener is not a 
function
 at ExampleComponent.componentWillMount (ExampleComponent.jsx:19)
 at ReactCompositeComponent.js:348

Initially this is confusing, since it’s clear we did already declare addChangeListener, so why is this error saying it’s not a function?

The catch is in how we export the Store. The cause of my issue above was that I had exported it like this:

class ExampleStore extends EventEmitter {
..
}
export default ExampleStore;

This is how you would typically export a module but what we’re trying to do is treat the Store as a singleton instance. To do this the export should be:

export default new ExampleStore();

This approach is described in many Flux related articles (here’s an example), but it’s an easy mistake to miss.