Adventures in Fronted Interviewing - The Take Home
Tags: career, frontend, interview
Published: 2021-11-11 03:44:27

During my recent job search, I was exposed to how different companies run their interviews. Two of the companies I interviewed with asked me to complete a takehome challenge as opposed to doing a live codescreen. The idea is to give you more time and flexibility to do it on your own schedule. This also means that instead of a 30-45 minute window to complete one or several code tasks live, you have a few days, maybe a week, to complete a broader set of tasks that would involve more complexity. 

[A little more about me](https://dev.to/khayden73/allow-myself-to-introduce-myself-1999)

For both takehomes, I had to learn tech that I was not familiar with instead of having the choice to use what I know. I consider myself to be very good at taking mockups from designers and specs from product managers and creating a responsive interface. Making me do it "their way" adds complexity and doesn't really showcase my skills and experience.

## It should only take a couple hours

For the first of the take homes, I was assured that "It should only take a couple hours". It ended up taking me a few hours a night for a few weeknights after work, and then about 6 hours on a Sunday to wrap it up.

They sent a zip file that contained a README, a mockup of a data card, and two json files. The README contained a list of requirements like:

1. bootstrap a new NextJS app using `create-next-app`
1. Add TailwindCSS as a dependency
1. Create two api endpoints that return the data in the json files
1. update index to fetch the data from endpoints
1. create a "loading" component to display while data is fetching
1. create a card component to display the data for each item
1. Use Flexbox to render cards in a grid with media queries for breakpoints listed

They didn't go into detail about how much of tailwind I was expected to use. I'd never used it before and when I started researching it, I was kind of horrified to see how it worked. Creating utility classes isn't itself a bad thing, but basing your entire layout on littering your markup with classnames seems like madness to me. At the very least I included the tailwind base, components and utilities in my global css file. But ultimately I ended up just rolling my own CSS because I was more concerned with getting it done than with getting it done "with tailwind". I'm very much a CSS geek and I love experimenting. I can learn any framework on the job so I wasn't enthused that it was a requirement.

For creating the project with NextJS, I'm lucky because I've done that before. My personal site is a NextJS site and I had already been through the learning process for that. NextJS was actually relevant here because it was in the job description and we did discuss it on the initial interview.

The requirement to use flexbox for the grid didn't feel right. During our call I spoke about how I loved CSS grid and was immediately told, "we can't use that because we still have a lot of users on Internet Explorer". I understand the sentiment behind that, but it's a bit uninformed and forces me into a box instead of allowing me to show how I would solve it. Who knows, maybe they'd learn something from me. But I digress. I'd never used flexbox to do grids in this way so that was another thing I'd have to experiment with. My use of flexbox usually involved a container element aligning children in a row or a column but not as a grid. I also haven't had much cause to use properties like grow/shrink.

For the API endpoints, Next makes it real easy and all I had to do was read in and return the contents of the json files. The data consisted of 34 items in one array, let's call them "teams" and 400 in another, let's call them, "players". Each player had several properties, including an id that cross-referenced the teams data set. However, the documented schema said this id would be an integer, but it turned out to be a three-letter string. The fact that I figured that out after their mistake should be a point in my favor.

I setup two variables using the `useState` hook to hold the data from each and `async/await` to fetch them from the API. I used `useEffect` to make those API calls only after the component had mounted (like `componentDidMount` would do in a class component). Then I did something like this in the component's return:

```
<main className={styles["page-content"]}>
    {playerData.length > 0 && teamData.length > 0 ? (
        <PlayerList players={playerData} teams={teamData} />
    ) : (
        <Loading />
    )}
</main>
```

Then I spent quite a bit of time obsessing over layout of each card and the overall page. I started out just using 20 items to get the layout details ironed out, then started having it load 50, 100, then all the data. 

There were two more problems with the data that I discovered at runtime. The first was a handful of players had null values for some stats, so I had to account for that in the code. Each player also had a full static url to a thumbnail image but one of them was throwing a 404 and blowing up the layout. I made some adjustments to the css to cover that scenario as well. In my mind, finding and fixing bugs in the data or the layout is exactly what happens on the job. I called these things out in the README.

As a way to help me stand out a bit, I decided to use CSS custom properties for the colors and added support for dark mode using the `prefers-color-scheme` media query. I also used the `prefers-reduced-motion` media query to control the loading animation. The loading animation would spin slowly if `prefers-reduced-motion: reduce` but bounce otherwise. I felt like this showed that I thought about things outside the scope of what is asked.

So after all that, I pushed to my own repo and sent them the link. Then I waited...

It took them almost a week before I even heard from them to say they were going to look at it. Then it took another week to hear back from the recruiter with the rejection. I had to ask this 3rd party recruiter about feedback, and he had none, so I asked if he could ask them on my behalf. I had the hiring manager's email, but wasn't sure if I should email him directly.

> * Did I misunderstand something in the instructions
> * Did I not do something they were expecting?
> * Did I do something they didn't agree with?

After yet another week, I finally got something that barely qualifies as feedback. I was still just as perplexed as before.

> In terms of the code challenge itself, they mentioned that there's a specific layout that they look for in terms of how far you can break the code down. Since I'm not an Engineer, my interpretation of that is there could've been areas where the code wasn't as complex or in depth that they'd like. For example, didn't take it to its limits as much as it could've.

> It was hard for them to break it down into more simple feedback; the best way he phrased it was just that the layout and format didn't match what they hoped for.

As the interviewing company, they should be upfront and clear about their expectations, not cryptic and just see if someone does it how they like. Every candidate is different and has different experiences, but we're all pretty adaptable to change if we know what is expected. The lack of clear expectations and lack of feedback afterwards tells me that I don't want to work there.

## Takehome Challenge: The Sequel?

For the second takehome, I was invited to fork a private repo on github and create a branch. To submit it, I was supposed to create a PR against master branch in my fork. It was an already existing React app that I just had to run locally, and make updates.

There were **required** tasks and **extra** tasks.

The tasks were as follows:

### Required
1. implement the layouts for mobile/desktop according to mockups using Styled Components
1. create a scrollable component that shows 3 videos at once
1. Sort the videos alphabetically
1. This is not a design challenge, but use your best judgement to make the site look nice using Styled Components
1. make selected video autoplay when thumbnail is selected
1. (senior required) use redux for global state
1. (senior required) write tests

### Extra
1. implement lazy loading
1. use typescript
1. deep linking using React Router
1. write your own express server

Just like I had never used Tailwind, I had also never used Styled components or Redux. The project I worked on up to this point used MobX for state management. I did some quick recon on Redux so that I could set that up and know how to use it, but Styled Components drove me a little nuts. As a longtime CSS and SASS geek, I got a little frustrated with learning a new way to do CSS.

But here's what I did:

1. implemented layouts for mobile and desktop using Styled Components
1. loaded video thumbs in scrollable component
1. sorted alphabetically
1. made it "look nice"
1. had issues with autoplay because of browser restrictions
1. used redux adding data to the store
1. added deep-linking with React Router
1. added some tests using React Testing Library
1. attempted to add typescript but the existing app had dependency issues and I opted to leave that in a branch and made note of it in the PR
1. I added lazyloading to thumbnails using `loading=lazy`
1. added prettier and eslint (wasn't required, I just like it)

I submitted the PR, sent an email and waited a week to be told "the team is passing on your candidacy". No more details, no followup to review my code or ask questions, no feedback about what I did wrong or what I did right (which is just as important). Just ghosted...

## Conclusion: I didn't enjoy the takehome experience

The idea of a takehome should be to give the candidate more time to do the task at their own speed. Having requirements to do things a certain way just adds complexity and doesn't consider that not all candidates have used everything in your tech stack. Let them complete the challenge the way they want and then have a followup discussion. Not everyone who is good at Typescript and CSS-in-JS can figure out an npm module dependency issue or webpack config.

Making someone use unfamiliar tools or mess with dependencies feels like you're expecting too much time and effort from a candidate who has no guarantees of moving forward.

Neither of these companies had followup calls with me to discuss it. To me, that's a failure in their process. If I gave someone a takehome I'd want to review it with them afterwards because it would reveal a lot about their thought process, how they handle challenges.

While not all codescreen interviews were great either, I'd have to say these two experiences have soured me on takehome challenges.