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!
I managed to snatch a free ticket for the 2017 AngelHack, so I was off to another hackathon!
My team and I created HackGen, which grabs DevPost data and displays winning hackathon idea randomly, often resulting in quite hilarious results. Seriously, my team spent a good portion of time after code freeze in laughter. Some people’s hackathon idea makes no logical sense. I can only deduce that they wrote it after a long all-nighter and did not presented their project that way on stage.
For this hackathon, I participated predominately in the front-end features, making sure the data that my teammate, Ting-Wai To and Michael Snowden, are displayed in an aesthetic, user-friendly manner. Consistent with my coding habits, the site uses responsive design. The languages I used included HTML, CSS, JS, Ajax, and jQuery. The framework we used was Django. We started trying to host the site on AWS, but ended up using Heroku. The VCS was Git on both Github and Heroku. Our project works with Amazon Echo and also allows visitors to subscribe by using the SparkPost API.
The site started with the name HackPredict and was supposed to predict the chance of success for an hackathon idea:
However, the collected data wasn’t enough for an accurate prediction. No matter what was input, the result remained between 40%-50%. Eventually, it developed into an idea generator:
And this is its final outlook:
Now, for the struggles and lessons:
In this case, I was reminded that Anaconda and Virtual Environment don’t play well together. My team had a lot of trouble. I was able to solved it by doing a simple conda install python=2.7.8. I think it helped that I have previously set up everything to work once already last month while working on a Slackbot with Django as backend. All I needed was to switch from Python3 to Python2.7. The other guys sounded like they had bit more trouble.
I also ran into trouble with static file management in Django, which according to Michael, is a common problem. When Ting-Wai wanted to use Bootstrap with static url, Michael and I were all going “No! Just CDN it!” Yea, we didn’t get along with it.
Ting-Wai apparently hates the Bootstrap progress bar, but Michael really wanted a progress bar. So, I went with a customized dot progress bar. Fortunately, while I know Bootstrap, I often practice coding in raw CSS to build my foundation, so it was easy to whip one up:
My teammates were surprise that I didn’t use Bootstrap at all for the site. I actually did started with Bootstrap, but I wanted more customization on the input and buttons. Besides, almost everyone use Bootstrap with very few customization in a hackathon, so why not take a different approach? For a small site, raw CSS is pretty easy.
I also had trouble once my teammate set up mysql with Django. I first got “Did you install mysqlclient or MySQL-python?” error, which persisted even after installing those packages. Following online suggestion, I homebrewed mysql-connector-c, which turned out to be a Python3 suggestion. I got a “Segmentation fault 11” error and wasn’t able to do a runserver at all. I uninstalled mysql-connector-c and looked up for new solutions. The golden solution:
*Sighs* I swear, setting things up probably took more time from my team than coding. I am not the one in charge of set up, but I can tell by the way my teammates acted. If this is an anime or cartoon, they would probably had smoke coming out of their ear. One of them rushed to a couch for a nap right after demo. There were a lot of demos too. The hosts had to divide us and the judges into 2 rooms, and I think we were the last few teams to demo.
I got to brush up on my front-end skill during that weekend and hang out with a lot of cool people. Got a bunch of nice goodies:
Amazon have notebook, t-shirt, and ninja sticker – who don’t like ninjas!? IBM have cool hexagon sticker and external usb port, the later of which I totally need for my Chromebook (only 1 usb port there). SparkPost is my favorite since I am a sticker collector: they have grid notepad and awesome stickers. Apparently, they have all the languages they supported sticker-ify, plus one more design for our beautiful Golden Gate Bridge!
All in all, it was a good hackathon, with awesome people, good amount of API challenge choices, cool goodies, healthy food and plenty of coffee, and a lot of fun demos and ideas.
We started off with the Lightning Talks, and the first one up is Joshua Nelson from Atlassian. His original topic line is “Component libraries and React as a platform”. The final version of his topic? “Why Lego is Great”!
Lego have a rich history and culture, which Joshua started his talk with and eventually turned it around to Atlassan’s component library, discussing its 3 key advantages: Clean API, Reusable, and Platform.
Then Michael Leung and David Katz talked about their Reactathon project. Utilizing the OpenTable API, their project BrokenTable determines which bar is most likely to have bar fight.
Yep, bar fights.
All while the developers are students too young to even step into a bar.
Needless to say, the idea was hilarious, and the duo succeeded in giving a presentation that was both funny and educational. I particularly enjoyed their presentation of how their code works and how they implemented React Native and Redux in the fast-paced environment of a hackathon.
After a brief break, Feature Talks started, with the first one being on of my main goal for attending this Meetup: “Going GraphQL First on Web and Mobile” by Jon Wong from Coursera. I am considering GraphQL for the next on my to-learn list, so this is perfect timing!
Jon discussed about the task to implement GraphQL in an existing project – a task he found similar to what Justin Bachorik mentioned in the Reactathon talk regarding NPR’s transition from legacy code to React. Both are accomplished through the process known as incremental adoption.
Speaking of, I have been studying Redux, and I don’t envy the future me that will eventually adopt Redux for my React project. Incremental adoption indeed.
Jon touched on how Joshua talked API contract earlier in the Lightening Talk and stated that GraphQL inverts API contract back to client, who is the the one to actually build product. Such schema-first approach helps create better contract.
For someone planning to learn GraphQl, his description is helpful in giving me an idea of what and why I should learn it. His diagrams also did a great job in graphically representing how GraphQL works with React’s Component-focused system.
The last but not least (oh, definitely not least) is Berkeley Martinez, CTO at freeCodeCamp. Perhapes a reflection of his work, he is quite excellent in teaching – seriously, I have zero clue of what Observables when I started. Yet, I wasn’t lost with the amount of codes he displayed, and I came out with a pretty good understanding. He was very good at being precise yet informative and to the point.
I must say, this Meetup was one of my most satisfying I had. Meetup that shows lots of codes and teaching materials can be dull if it is not a tutorial everyone can follow. Not a lot can be fun, inspirational, and technically informative. This definitely hits all the spots. I can’t wait to attend another one!
Another hackathon? Do I really want to do two hackathon in a month? On the other hand, my last hackathon was as fun as it was intense. I really enjoyed it. Plus, this hackathon is hosted by Stanford library with digital archiving as the theme.
Archiving. Library. My inner bookworm is dancing. (Or wiggling?)
The hackathon was part of the PDA Conference. While I didn’t got to attend ($120 for late non-student registering), listening to the participants, the conference seemed to be very well done and highly-praised. They sounded so enthusiastic, particularly about the keynotes and agenda selections, that even I felt excited!
For me, the excitement was also twofold compared to a normal hackathon. I obviously enjoyed the chance to code a project with practical usage in a team environment. But I had also been a library assistant, a teen library council member, and an art history minor student. My love for the history of fine art and literature started when I was just a kid. To be with so many that shared the same interest was rejuvenating after so fully engaged into the tech industry in the last 2 years of my career change.
Naturally, when one of the attendee, Katie, talked about her intention to do a project that address email archiving issues related to her work as an art archivist, I was hyped up!
Art + Archiving = I Am In!!!
Our team decided to build a web platform that organizes and analyzes email in a shareable way. Having an art archivist that is passionate about her work really helped directed the project. While I had looked into Stanford’s email archiving software ePADD, without hearing Katie’s perspective as a professional, it was difficult to fully comprehend the importance of analyzing email and maintaining content privacy in the field of digital archiving.
Thus, with the project decided, our team “Girl With A PERL Earring” began our platform, Bubble Wrap!
Katie and Natasha, whom were both interested in art digital archiving, created the wire frame using Proto.io. Lakshmi, whom was interested in analyzing email, tackled extraction method for a set of sample emails. She applied the NLTK toolkit with Python to extract the data into the required JSON file for our project.
Inspired by the MIT Immersion project Katie showed me, I researched into the project’s background. I knew I saw a similar graph built using a D-something library and 4j-someting while attending a DevWeek presentation. I was right. Immersion was a force-directed graph built using the data visualization D3 library and graph database Neo4j.
And the sample codes. It looks understandable.
I think I can do it.
Gosh, it would kill a lot of my brain cell. I mean, an entirely new library in less than 12 hours?
But yes, I can do it. Let’s do it!!!
Thus began an intense all-nighter that I haven’t attempted since I left architecture school. I did got 3 hours of sleep, but the impression that I didn’t sleep apparently got stuck in the event host’s mind. My teammates were also impressed with my energy. I have a feeling the most memorable part the library host and my teammates will remember about me is that I don’t need to sleep.
But hey, the result was worth it. The data visualization I created looked beautiful, and I learned so much!
D3 required a good grasp of SVG and not just basic CSS styling. I struggled with labeling the circle (it seemed to be a known issues. Text couldn’t just be drawn on the circle) and DOM query (SVG have their own set of query method).
I didn’t have time to go through tutorials, so I quickly analyzed sample codes that seemed applicable. From there, I selected specific methods to research. Force, a D3 module, have its own rules and requirements. In particular, it takes the array key, “source” and “target”, from the imported JSON file. I had changed the JSON keys to make it more applicable to our case, so I was confused when nothing was printing.
As morning came, the essential features of my graph seemed completed.
Then another issues occurred – our presentation is on Proto.io and Google Slide, so how do we present a dynamic demo? At one point, the discussion involved taking snapshot, but it would defeat the purpose of a moving demo. So, I quickly whipped up a Heroku page, looked into the right webpack (static), and pushed my code up. There, a dynamic demo site!
Proto.io was beautiful – elegant but clean. Sadly, while Lakshmi got the JSON set up, it was too late to link it to my D3 script. I ended up using a modified dummy code from the D3 tutorial. Fortunately, Lakshmi set a flowchart in advance, so she was able to go over how the Python script work.
To our excitement, we won a prize! The prize was for – and since it is long, I dared everyone to say this in one go really really fast – “Most innovative project relating to email management or archiving”.
In total, I learned a whole new library in less than 12 hours, met new friends, got to hang out with archivists, listened to some really cool conversations, and won a prize. All in 12 hours!
That was the question of the day for my team and I last Saturday, when I attended the 2017 All-Women Hackathon hosted by Expat Woman at Pivotal Lab. The Hackathon have 7 challenges, as listed in their Eventbrite:
Engage more Girls in STEM
End the Gender Gap in Tech
End Gender Violence
Teach Boys/Men to Respect/Empower Women
Help Immigrant/Refugee women Navigate the US
My team’s chosen challenge is Women’s Safety, and the project idea stemmed from the experience of our team members, when some random guy just started yelling at them outside the street Pivotal Lab. The incident motivated Grace to go up stage and pitch her ideas, which brought our team together, which consisted of Grace, Magda, Daminika, Anju, Steph, and I.
Our project is a web app would let user to search their destination using the Google Map API, but instead of just seeing the route, they will also see safety ratings. The rating would be generated from a combination of crime data and user feedback, showing keywords that indicates incidents that occurred. Users would be able to filter and customized feedback result base on time of travel and gender. Upon research, I saw that SFPD have Socrata OpenData set up. With the combination of the OpenData and Google Map API, the path to map a safe route in real-time is not far!
To coordinate our pace, Grace took the advice from one of the hackathon mentor to set up a hourly timer, and I started to write a to-do list that will let our teammates assign themselves to different tasks. Even though I introduced myself as a front-to-full developer, interestingly I ended up working with Grace to establish the data parameters that the app will query.
Doing our initial brainstorming, deciding on the project’s direction and presentation content took a lot of discussion. Thankfully, we had a good group of mentors who would periodically come by to talk with us.
In the end, we were able to get a Google Slides set up, a demo video recorded, and time to rehearse our presentation, all in 11 hours! Somehow, I ended up being the presenter, which was a bit nervous-inducing. Thankfully, it went smoothly.
Overall, it was fun to work on the project with my teammates, and my experience at this hackathon was very satisfying. We didn’t win the physical prizes, but the experience was a prize of its own.
Last Saturday, I volunteered to help students with coding tutorials in the first application workshop of Techtonica, a new San Francisco non-profit that offers free tech training for low-income women and non-binary adults. Interestingly, I myself was studying coding tutorials for React the night before.
On the morning of the application workshop, I put a pause on my React studies and did a quick review of the Django Girl tutorial, since I remember reading that Techtonica hosted Django workshop before. It was pretty familiar materials, and really, how in depth can a first-day workshop be? Yet, as I walked to the workshop site, I found myself feeling unsure, both about whether I should start my web app already and whether I can teach coding well.
In the end, my worry about the workshop was unwarranted. The students went through a tutorial that introduces basic HTML and CSS. Not only did I not have any issues helping them, I truly enjoyed the experience of sharing what I know.
I signed up for the last of 5 workshops. It was a small workshop where there were about 6 to 8 applicants. Volunteers and students shared the table, so interactions were easy and the environment was pretty relax and open.
Most applicants seemed to do fine in the tutorial sets and finished it in the requested time frame. The tutorial leaded up to a personal web page. After the tutorials were completed, the applicants got called in individually to be interviewed by the staff while the rest could continue to improve and practice on their own page. They also got to present the resulted web page that their tutorial codes created. In between, there were questions and chats, mostly related to basic HTML/CSS and additional tutorial recommendations.
I found myself reminiscing on how I started coding and how far I have came. Back then, there were no interactive tutorials like Code Academy or FreeCodeCamp – the most popular recommendation during the workshop. Coding wasn’t even a word in my dictionary, until I saw a deceptively thin book on WordPress website while I was shelving books in the college library I worked at.
Now, I can build a website off the top of my head. I can explain to the applicant in the workshop what html tag to use, what css to change, and troubleshoot their codes.
True to the old saying, when you help someone, you end up helping yourself as well. By the end of the day, I felt energized and inspired by what I was able to do and how much I can help others. I went back home where I finished the tutorial set I am on, closed the browser window, and made a new directory.
I love customization. Which is also why ever since I won a Chromebook during a HTML5 Meetup (Hooray!!!), I have been thinking about installing Linux on it. Finally, I got around to it!
Firstly, I debated on which Linux OS to get. The most popular one seems to be Crouton. However, I eventually decided on GalliumOS, because it was specially designed for Chromebook and seem less likely to break on updates – at least according to what people are saying online. Plus, built on top of Xubuntu, GalliumOS is a fully functional desktop. I would sacrifice some GPU performance, but I think it’s worth it. I will be working predominately in Linux instead of ChromeOS, so it is a good exchange. The simple-to-follow wiki guide from GalliumOS also is another plus – hurray to good documentation!
Secondly, following the wiki, I identified my hardware and its associated flash firmware requirements. My Chromebook is an Acer Chromebook 11, CB3-131. According to the Hardware Compatibility page, it is a Bay Trail model, and thus require custom firmware. Using Firmware page, I chose to use the firmware update of RW_LEGACY from MrChromebox – RW_LEGACY would allow me to duo-boot and I don’t have to open up the Chromebook and remove the write-protect.
The process was pretty smooth. The powerwash did took a while as the guide stated. The white developer mode boot screen appeared and stayed there for a while before the screen emits 2 loud, alarm-like beeps that had me a bit worry. Fortunately, it was a false alarm and a setup panel for ChromeOS appears:
I logged into my wifi and log into the crosh shell as instructed:
Looking good. Now is time to update my Legacy Boot capability, which in my case, is the RW_LEGACY from MrChromebox as mentioned earlier. After that, to get back to the ChromeOS login screen, I restarted the laptop. The 2 loud beeps happened again and I got back to the ChromeOS setup panel, which shows that I am still logged into my wifi.
Finally, it was time to install GalliumOS. I had 2 choices, the standalone setup that uses a bootable USB and dual-bootup that uses chrx install script. I decided to go with the dual-bootup. The process for that was also pretty smooth. I followed the steps and went with the recommended 9 GB space allocation:
After chrx rebooted and “repair” the laptop, I have to run the chrx installation script a second time:
There were some confusion as the second run of the chrx install script didn’t seemed to work, which turned out to just be a disconnected wifi. After that, it was a smooth sailing!
I set up my chronos account password, and the rest is just customization all I want! I found a reddit for GalliumOS, and got some good recommendation from the post What To Do after installing Gallium OS: A noobie’s Guide for other chromebook noobies. Some softwares I added were Firefox (with all my favorite addons: ABP Adblock, NoScript, Blur, Firebug, and Pocket), PIA VPN, Cisco AnyConnect, VIM, Sublime Text, GIMP, LibreOffice Writer, and Gnome Software Center.