Singapore’s Grain Eats Up US$1.7M For Its ‘Full-Stack’ Food Delivery Service

As reported by Jon Russell at TechCrunch on 20 January 2016. More details can be found here.

Grain, a Singapore food tech startup, has landed funding to build out its “full-stack” approach to food deliveries in the Southeast Asian city-state. The Series A round is officially undisclosed, but TechCrunch understands that the total amount raised is SG$2.45 million, or US$1.7 million.
The financing was provided by a collection of investors, including NSI Ventures (lead), Ivan Lee (who founded and sold Thai Express in Singapore), 500 Startups and Digital Media Partners (DMP).
Rocket Internet-backed FoodPanda dominates the food delivery industry in Southeast Asia, the wider Asia continent and other emerging markets thanks to a major acquisition spree last year that saw it acquire nine competing startups worldwide.
FoodPanda and its ilk act as a middleman between restaurants and consumers, but Grain differentiates itself by handling all stages itself — from preparation and cooking to order management and the delivery itself.
“What we’re building is a bit more nuanced [than services like FoodPanda],” Grain co-founder Rifeng Gao told TechCrunch in an interview. “We’re like a restaurant on the cloud, [when] you want good food that’s convenient, we want Grain to be the first thing that you think about.”
Grain keeps its menu deliberately narrow with four different meals available each day on a selection that rotates weekly. Meals are priced between SG$9.95 and SG$12.95 (approximately US$6.90 to US$9) with a varying delivery fee. Customers in the busiest areas don’t pay anything for delivery and have no minimum spend, but those in quieter zones are charged and must hit a minimum spend.
That model enables the company to be unit profitable, Grain co-founder Yi Sung Yong said, which is something which FoodPanda isn’t able to do. (FoodPanda splits its orders into buckets: those it loses money on, those it breaks even with, and those it is profitable on.)
/** * helper function to take the form and * get back a js object with field/value mappings * ignoring submit fields and fields whose name we can't ascertain */ function serialize(form){ return Array.prototype.slice.call(form.elements) .filter(isInputElement) .filter(isNotSubmit) .filter(hasFieldName) .reduce(function(data, node, index) { data[getFieldName(node)] = node.value return data; }, {}); } /** * Check if this form element is of type input */ function isInputElement(node) { return node.tagName.toLowerCase() === 'input'; } /** * Check if this is a 'submit' input element */ function isNotSubmit(node) { return node.type !== 'submit'; } /** * Ensure field has a derived name */ function hasFieldName(node) { return getFieldName(node) !== 'unknown'; } /** * Attempt to ascertain "name" of field. * * they don't give inputs real `name` attributes, so * best guess is to hack around the element's label text, * falling back to the placeholder text. (their html is * not semantic and often labels erroneously reference * parent divs instead of sibling input elements) * * strip out the stars they show when validation fails * * if label is misplaced _and_ there's no placeholder, * this function is insufficient */ function getFieldName(input) { if (!input.labels.length) return input.placeholder || 'unknown'; var labelText = input.labels[0].textContent.trim(); return ~labelText.indexOf(' *') ? labelText.slice(0, labelText.indexOf(' *')) : labelText; } /** * Listen for form submissions and send identify * if you'd like an event too, just delete the '//' in the track line */ document.forms[0].addEventListener('submit', function(e) { analytics.identify(serialize(e.target)); // analytics.track('Submitted Form'); });