“Damn, those kids are smarter than me!” I whispered to Jessica, who laughed and playfully slapped me in the arm. We watched in awe as the kids – middle schooler going to high school – talked about wanting to build their app in Java and the algorithm involved (“I didn’t know computer existed when I was in middle school!” “…We sound so old!”). The joy of hackathon – you see all sort of ideas and participants.
I was at DocuSign HQ for Hacking for Humanity, hosted by Girls in Tech and Hackbright and sponsored by DocuSign, Cisco, Kintone, Handshake, Memebox, and JINS. Topics we can select may include Homelessness, Sexual Assault, Domestic Violence, Human Trafficking, or Women’s Health.
The host decided to assign us into teams in advance. Like all events though, we have a bunch of MIA attendee – Missing In Action. So, those us missing members waited in line for reassignment. While there, I started chatting – which led me to me be invited into another team before the re-assignment.
We started as 4 person team – UI/UX designer Jessica and Tawny, software engineer Anoja, and myself as web developer. The host wanted a 5 person, so they assigned us Ryu, engineer and Kintone evangelist visiting from Japan.
Opening talk took the whole morning – Hackbright even did a Coding 101! For me, the most interesting part was listening to SF Safe House and Women Inc’s work and mission.
Since this hackathon didn’t have idea pitching, our team are formed without a project idea or even a common topic interest. My team eventually decided to go with Women’s Health: HerCare, a web app that extracts SFGov Opendata and list nearby free health care clinic, then help user to easily find transportation route.
Styling in React
fetch() and Component Lifecycle
For some reason, console.log revealed that the state is not setting with the data I retrieved in fetch() when I use the OpenData API. Looking into React’s fetch(), I learned that it returns a promise that must be waited. Meanwhile, render() is also setting state and mounting. To ensure the state are set in the mounted component befire re-rendering is trigger, API calls with setState() should be done in componentDidMount().
Latitude & Longitude via Google Map API
While trying to get Google Map working, I spent too much time on the wrong npm packages. I had picked one of the recently updated one with a simple example, thinking it would be a snap.
Fortunately, when I finally switch to a different one someone recommended in Reddit (react-gmaps), it worked almost right away. After that, I needed to get the latitude and longitude by address – regular user obviously wouldn’t be entering their latitude and longitude.
Having been working with bunch of npm packages lately, I jumped onto the npm-package-solution again. Silly, since it turns out Google have an API for that.
*Sigh* The precious hours… Almost submission time!
Controlling State Updates via componentWillReceiveProps() & componentDidUpdate()
When users clicked on the parent component, LocationList(), which holds the address, it should updates the child component, GoogleMap(). The update involves calling the Google API that detects latitude and longitude.
So, another API call. I would use componentDidMount(), right? I mean, the React doc say so itself:
If you need to load data from a remote endpoint, this is a good place to instantiate the network request.
…yea, didn’t worked. The question is why?
Well, the thing is that the map component (GoogleMap in this case) was first mounted, then its states changes when the parent component (LocationList) holding it passed down a new prop that activates an update – not a new mounting. What I need was componentDidUpdate().
But when I did the API call in GoogleMap and use setState to update the states with latitude and longitude data, the component itself will update, again.
This is an infinite loop.
That’s where componentWillReceiveProps() came into use. I set up a flag variable, “updated”. In the constructor, it is initialize as false. Inside componentDidUpdate(), an if statement checks the flag. If false, we do the API call, setState, and set “updated” to true. After that, the subconsquent update from state change will not activate another API call because the flag variable is now true. Only if the component receive new props from the parent component LocationList(), – in another word, someone click one of the address listing – would the variable “updated” be set to false and thus activate the API call.
Deployment on Heroku
Unfortunately, I didn’t solve the infinite issue until after the submission. Fortunately, I have continuously deploy my site onto Heroku. Deploying React onto Heroku is acutally a snap. The Heroku team have a instruction page just for that: Deploying React with Zero Configuration. I do have do a npm run build to get it running, but after that, it’s smooth sailing.
The challenge of this competition was definitely communication and task distribution. It was a bumpy ride, but we eventually find our rhythm. Both Anojo and Jessica was inspired to do more hackathon, so I recommended July’s AngelHack in Silicon Valley to them – we will probably bump into each again as a result!