Looking for a simpler way to work with the SproutCore store and records

This post is about SproutCore programming and assumes familiarity with the framework.

The traditional pattern of working with store's records is to set up a binding via a controller and handle a data change event. At high level, it goes something like this:

1. Request the creation of RecordArray via App.store.find(<some query>) method
2. Set the record array as the "content" in an ArrayController
3. Bind a view to the content property of that ArrayController

First two steps are done together, usually when a state is setup. For example, say you want to show some contacts. You'd write some something like this:

App.contactsState = SC.Responder.create( {
didBecomeFirstResponder : function() {
var records = App.store.find(App.contactsQuery);
App.contactsController.set('content', records);
}
});

The third step of binding is done in a view eg.

view = App.ContactsView.design({
contentBinding : 'App.contactsController.arrangedObjects'
});

This pattern works great when you need a static relationship between a piece of data and a view. In this example we have a static binding between a set of contacts and the view that shows them.

However there are cases that don't call for a static binding relationship. Cases where an app simply wants to make a query, get the data, and act on it. These cases usually happen then an app needs to process a event eg. user action (button click), or server response. Handling these cases is quite convoluted with the pattern above. 

For example, say you need to implement a button that sends a message to a subset of your contacts eg. "favorite contacts". 

You cannot write:

onClickSendMessageToFavoriteContacts: function() {
var favoriteContacts = App.store.find(App.favoriteContactsQuery);
favoriteContacts.forEach(function(contact) {App.sendSomeMessage(contact);});
}

because find() cannot return the results when they haven't been retrieved yet (from the server, from local DB, etc.). By the time find() returns the RecordArray favoriteContacts can be empty and would be in the BUSY_LOADING state.

Instead the button handler would have to do the following:

1. create a new query -- because we want to select a subset of the data given a specific criteria (eg. select favorite contacts)
2. create a new controller -- because we need a way to be notified when the results of the query are available
3. setup an observer/binding that will wait until the results are available 
4. perform the action (sending a message to favorite contacts)
5. tear down the observer relationship -- because we no longer interested in paying the cost of having "favorite contacts" be kept up to date
6. remove the record array -- because the array is no longer needed and would simply take up memory

Ideally we'd want a more direct way to act on the results of queries. Imagine being able to write:

App.Contact.objects().filter({varotite: YES}, function(contacts) {sendMessage(contacts);});

A filter() method would perform all the necessary steps to make sure that when the callback is called, the data is available. It would also tear-down all the bindings needed to make it happen. Similarly, one can imagine an API like:

App.Contact.objects().all().del()
or
App.Contact.objects().all(function(records) {dome something with all Contacts})

Those who are familiar with Django will recognize this API as similar to QuerySet (http://docs.djangoproject.com/en/dev/ref/models/querysets/), but modified to deal with asynchronous nature of JavaScript programming.

Getting an object would become:
App.Contact.objects().runGet({guid: '123'}, function(contact) { do something with contact 123 });

A multi-step operation such as getting or creating an object can also be hidden inside a method (see Django's version here: http://www.djangoproject.com/documentation/models/get_or_create/):

App.Contact.objects().runGetOrCreate({firstName: 'John', lastName: 'Lennon'}, {'birthday': '1940-10-9'}, function(john) { ... });

I've put an implementation sketch here: and would love to hear any feedback. It is structured as a mixin to the Model and tracks the record states in order to call the callback at the right time.

Do you think SC's data model API should be improved? Can it be improved? Am I approaching the implementation from the right perspective? Does this idea have any fundamental issues with performance?

Stanford's Entrepreneurship Corner: Marc Andreessen

Great Q&A on entrepreneurship.

Marc Andreessen is soft-selling his new VC fund, but he does it in a way to provide a real value to listeners beyond letting them know about his investment philosophy.

On criteria for selecting a business idea.

It is quite similar to criteria of selecting an investment:
1. Biggest market (new or existing)
2. 10x change in technology (or economic change). The premise is that existing companies "generally do a good job" at what they do, so you need a leverage of a profound change to start a new company
3. Team that includes at least one technologist. Two is better than one.
4. A product that becomes a company is better than a company that decides to build a product.

Q: "Can a mobile app company have enough potential to fundable?"
A: "It depends".
He is avoiding category-based investment decisions or presuming anything about company's potential simply by the fact it belongs to one or the other category. Example he gave is "enterprise software" was considered dead category in the begging of 00s, but resulted in great investments.

On building a team:
Recruiting and talking people out of quitting are the two hardest things to do at a startup. Selling a vision is a key skill for the funding team.

Great point about the value of "polarizing" product. It is OK to have lots of people hate the product as long as there are people who really love it. Describing your company in stark terms helps filter out candidates who aren't the right fit anyway.

StartupSquare Montreal and MTL NewTech

Montreal is a happening place. There’s StartupDrinks. There’s the launch of a new seed fund, Founder Fuel. The announcement of another StartupCamp. There comes two new players: StartupSquare and MontrealNewTech.

StartupSquare

StartupSquare Montreal

StartupSquare is hosting their kick off event on April 13, 2010. The group is made up students at McGill University, Concordia University, HEC Montreal, and other local universities. The goal of the group is to help promote entrepreneurship and commercialization to create growth companies. It is roughly modeled on Aalto Entrepreneurship Society which was started by StartupSquare co-organizer Riku Seppala.

Montreal New Tech

Montreal New Tech

Montreal New Tech is headed by Felipe Coimbra aka TwtFelipe who got some coverage this week by Mark Suster around US immigration policy and the Founder Visa. MTLNewTech is a great example of the evolution of community. It has taken the best part of DemoCamp, Web Innovators Group, TECHCocktail and other events over the past formative years. And it has evolved to help enable, educate and connect local tech entrepreneurs, i.e., it’s Felipe doing the things that help him with 63 Squares and YowTrip!

It is great to see entrepreneurs take responsibility for ensuring that the events and activities they need and want are created. Make sure you check out both of these groups, they are doing great things.

Amazon Simple Notification Service

Amazon continues to run away with this cloud thing. Its new service is called "Simple Notification Service" and it appears to do what it says:

Pastedgraphic-1

Create Topic "My Topic":
POST http://sns.us-east-1.amazonaws.com/?Action=CreateTopic&Name=My-Topic
Subscribe to "My Topic":
POST http://sns.us-east-1.amazonaws.com/?Action=Subscribe&TopicArn=sns.us-east-1.amazonaws.com/My-Topic&Protocol=https&Endpoint=https://myapp.com/mytopic/
Publish "hello world" to "My Topic":

Delete "My Topic" when you're done:
POST http://sns.us-east-1.amazonaws.com/?Action=DeleteTopic&Name=My-Topic

Google Code Blog: OAuth access to IMAP/SMTP in Gmail

Google has long believed that users should be able to export their data and use it with whichever service they choose. For years, the Gmail service has supported standard API protocols like POP and IMAP at no extra cost to our users. These efforts are consistent with our broader data liberation efforts.

In addition to making it easier for users to export their data, we also enable them to authorize third party (non-Google developed) applications and websites to access their data at Google. One of the more common examples is allowing a social network to access your address book in order to send invitations to your friends.

While it is possible for a user to authorize this access by disclosing their Google Account password to the third party app, it is more secure for the app developer to use the industry standard protocol called OAuth which enables the user to give their consent for specific access without sharing their password. Most Google APIs support this OAuth standard, and starting today it is also available for the IMAP/SMTP feature of Gmail.

The feature is available in Google Code Labs and we have provided a site with documentation and sample code. In addition, Google has begun working with other companies like Yahoo and Mozilla on a formal Internet standard for using OAuth with IMAP/SMTP (learn more at the OAuth for IMAP mailing list).

One of the first companies using this feature is Syphir, in their SmartPush application for the iPhone, as shown in the screenshots below. Unlike other push apps, Sypher's SmartPush application never sees or stores the user’s Gmail password thanks to this new OAuth support.

We look forward to finalizing an Internet standard for using OAuth with IMAP/SMTP, and working with IMAP/SMTP mail clients to add that support.

By Eric Sachs, Senior Product Manager

Wanted: Greasemonkey script to share Hacker News up-votes

How's this for a mouthful? What I want is actually quite simple, if you know what is Greasemonkey and Hacker News.

Need more detail? Let me explain: I read Hacker News. Sometimes I up-vote the posts. I wouldn't mind sharing those stories on Facebook, Twitter, this blog, but can't bring myself to make another half-dozen clicks to do so. Call me sharing-lazy. Hacker News is a minimalist/low tech news site, so I don't expect his author to introduce such integration anytime soon. But that should not stop a developer from adding it via greasemonkey script.

Perhaps good folks of Posterous would be interested to supplying such a script that automatically shares up-votes via post.ly?

How to Replace IMAP

I believe that one of the reasons for the lack of innovation in the email space is the lack of a simple yet powerful email access protocol. Every developer that wants to try something with email needs to first jump through the hoops of IMAP and MIME, or worse, the Outlook Object Model and MAPI. A new protocol like reMAP would lift this burden off their shoulders. We've seen what open, simple standards can do for innovation with Twitter's and Flickr's API. Now imagine unleashing the same sort of creativity to the vast ocean of data that is email.

Web apps that generate and host personal information are providing that information to apps via OAuth. Email - on of the key datatypes of personal information - is still only accessible via non HTTP protocol. It is time for a change.

I suspect that Google re-hiring Gabor (and killing reMail in the process) has a lot to do with this vision.