So, definitely haven’t been working on the app lately. It’s been another busy week – went to the Livability Award, added new features to the Sponsorlane dashboard, and attended the API World Hackthon. I ended up not the participating in the hackathon, but I got to check out some cool companies and played around with Citi’s new beta API.
React app wise, I only got to work on the async action testing, using Redux’s doc as guide. I also commented out a bunch of unfinished code so they wouldn’t interrupt when I start the test commands. As a result, the testing is working again, and I find some error in components file. The testing is also giving a false positive for the async actions, but that should change once I get the stores in and commented out a few things.
This time, I am going to post about a bit of troubleshooting with GalliumOS in my Chromebook. A little detour from my regular NextBus Compare project progress posting. This is more about working with developer tools, I guess.
I don’t actually use Chromebook that often since most of my work is on Macbook. As a result, it is not charge everyday. A few day, I forgot to turn it off. Left to its sleep mode, the battery completed drained itself.
If I just have ChromeOS, it wouldn’t be a problem – but my system is dual-boot with a Linux OS. GalliumOS to be precise. To boot into GalliumOS, I typically just do a simple Ctrl-L. But this time, there is an angry, angry beep and no boot.
I am almost certain it have to do with the battery drain, but what happened?
A bit more research on the documentation and GalliumOS reddit revealed that because the crossystem flag used for booting is a firmware level setting, it is therefore stored in volatile memory. When there is a complete drain, there is a possibility for the flag to be lost. To solve it, here are the steps:
Boot into ChromeOS – yes, not GalliumOS, but ChromeOS. We need to access the developer mode! Usually, the command for ChromeOS booting is Ctrl-D.
You may have to configure wifi if it is not set up. My Chromebook still remembers it, so it was good to go.
Do a Ctrl-Alt-=> (=> is the right arrow on the first row your keyboard) – to boot yourself into the developer terminal.
Enter chronos as username with no password.
Enter sudo crossystem dev_boot_legacy=1. Some guides online may say dev_boot_usb, but as the GalliumOS documentation mentioned, that flag is not related to legacy boot issue. I should know – I tried it!
For today, I started working on the actions file with redux’s own action documentation as reference. It seems their sample tend to favor seperating actions types and action creators into different files, but I think I favor keeping them one file for now so it is easier for me to keep track of things. I only have 3 actions types and 4 action creator for now anyway.
I also using redux’s Writing Tests doc, so the action creators are tested. I didn’t work on the fetchJSON() one though, because there is a fetch() there, making the action create async. The doc do have a section for async action creator, but I think I will do that next.
While I love volunteering at Sunday Streets as route captain, when the event is hosted at Alamo Square, my leg muscle does not love it.
For those who don’t live in SF, Alamo Square is on quite the hill. Sunday Street is an open street event, so the only way to travel long distance is by bicycling. As a captain, I was going back and forth several times to check up or resolve issues the whole day. Got plenty of exercises and vitamin D – but also got plenty of muscle sore to last the week.
I didn’t got much done on Sunday, and I pass out from delayed tiredness on Monday – thankfully I don’t have work that day. Naturally, there were no post updated yesterday. I am somewhat recovered today, so here’s some updates:
Prismatic to CodeColorer
After the last few post, I realize I really would like to post the codes I wrote without having to take a snapshot picture each time. It is probably best to go with a WordPress plugin for code snippet display, possibly with syntax highlight. There are several in the market.
Prismatic seems like a popular one. It was recently updated. Documentations and options are rich. Reviews are quite positive.
Sadly, the plugin didn’t seem to work.
Using Firefox’s Inspector, I notice that there are inline css that overwrites the styles for <code> and <pre>. I suspected it was the Edit CSS feature of Jetpack. Jetpack’s CSS tends to be loaded later in the process, so it have a higher risk of overwriting other plugins.
Unfortunately, I don’t fancy removing my Jetpack plugin. I did attempted to increase the loading order by turning the minification off using Jetpack’s own filter – jetpack_implode_frontend_css -, but it didn’t seemed to have any effects. Trying to unset CSS in the child theme’s Editor and Jetpack’s Edit CSS didn’t work either.
In the end, I just tried another plugin called CodeColorer. Now, that one works! I had to change some of the CSS to correct width issues with the line numbering column, but once that’s done, it works fine!
After some thought, I decided to start a new repo instead of sticking with my old Nextbus Compare repo. I am starting from scratch, so it is more of a rewriting a new app instead of a refactor. Create a new repo for a fresh start makes sense and would be much more simpler. The new repo will be Nextbus Compare V2!
So, create-react-app got started, testing environment is set up, directory is organized. Time to write more code than just test placeholder files.
It’s been over a month. so my memory of Redux is a bit blurry – but it’s ok, redux.js.org to the rescue! Reading their Todo List example and some of my old codes jogged my memory.
Here is the latest directory structure, with all the new files in. At the right is the current state of action creator, action.js.
There is also a basic combineReducer in reducers/index.js. So far, the test file just check that the files in the components are outputting div. For now, I am mostly just setting up some empty functions.
So, I was creating the directory organization for NextBus Compare. Looking at my previous sketches of possible file structure for my project:
plus being so new to Redux, I am going to stick with the tradition method of organizing it by function/nature. For those who want to read about React file organization, there are 2 articles that I found useful:
They each called the typical organization method different name – function or nature centric. François also advocated for what he called a domain-centric approach, while Mikey went with a feature-centric approach. I have personally done domain-centric before, and did like it quite a bit. For this one though, I am going to play it safe because my focus is to learn Redux here.
So here is my current file structure:
Task Two: Writing Test Files
Once there are new files, I tried to write test files to make sure all the files are loading, even though they only load empty div at this point.
Then I slowly realize that every googled posting for Mocha/Chai/Enzyme seemed to have different but very similar syntax. Therefore, I have a lot of tabs open but is very confused.
Eventually, I just close every tab, and search for the documentation for Chai and Enzyme. Restricting my reference source made it easier. Here is one of my test file:
There is a saying. Job hunting is a full time job. God, were they correct. I have been splitting my time between reading postings, researching companies, applying jobs, updating job site portfolios, interview prep, code testing (recently did a React app in 5 days), networking in-person and online, helping out at startup Sponsorlane, and still staying updated with tech news.
By the time Labor Day rolled by, I realized I haven’t worked on my side project involving Redux and mocha for over a month! Not to say I haven’t learn anything – I have been studying algorithm and design pattern. My debug and Node skill have also noticeably improved thanks to my effort in Sponsorlane. But I set up the goal to learn Redux and mocha months ago, and I want to finish what I started, damn it!
Thus, I am setting a new goal. I am going to re-start my app, Nextbus Compare. A fresh start. This time I will record my process: I will update my app one day, and post the process the next day.
So, here is Day One! The topic is:
Create-React-App with Mocha and Enzyme – with No NPM Eject!
The last time I tried to do this, there were multiple different sources of guides, most of them either confused me with too many steps or didn’t worked. I ended up doing npm eject. I also wasn’t what I did and what package I installed to made it work. This time, I am much more prepared. So, here is what I did:
I started with Dave Schinkel’s blog post, Mocha + Enzyme with create-react-app. It is a good read, although there are some things that don’t work with my system. Here is essentially what I did.
Since I don’t have yarn installed and babel-preset-react-app kept giving me import errors, I did npm install –save-dev es2015 babel-preset-react preset-stage-0. While Dave stated es2015 is ignored by create-react-app, I ended up needing it. The use of babel-core compiler later on resulted in import error because babel-core don’t recognize jsx. As a babel newbie, I don’t know why my outcome was different. I just know that babel-preset-react-app doesn’t work on my system. Please comment if you know why……
Modify “test” command to: “NODE_ENV=development mocha –compilers js:babel-core/register –require ignore-styles src/test/*.spec.js” . Note that in Dave’s post, his test command is missing the double quotes. Not a big deal, but if you were a Node newbie like me, know that double quote is required! Also, there is an additional –require ignore-styles here. That’s because if I don’t, babel-core will try to compile css files as js files, therefore triggering “unknown token” errors:
There are ways to bypass it, but I don’t plan to test my styles at this stage, so I am just going to do a simple –require ignore-styles in my test command line.
For testing, depending on if you also want chai or sinon, you would do npm install –save-dev mocha enzyme chai sinon react-test-renderer. Note that react-test-renderer is a a dependency requirement for enzyme. Without it, you will get this error message:
Here is a very simple test script I did in src/test/App.spec.js:
Mainly, the issue was node-gyp. Node-gyp is a command-line tool written in Node.js for compiling addon modules for Node.js. It bundles Chrome’s team’s gyp project, which helps with cross-platform issues. Alas, the tool itself ended up causing its own issues!
For me, there are two problem:
It does not support Python 3.
It needs make – a build automation tool – with its variable CXX set to proper C/C++ compiler toolchain.
In my case, my system’s default Python is 3 and the CXX is not always set to the right toolchain. So, first remove the local directory’s node_modules folder if you did a failed npm install earlier, then input this in the command line:
“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!