A Freeform Assignment
Tags: react, api, coding
Published: 2023-06-20 18:51:46

This was originally posted on [hashnode](https://sincerelybrittany.blog/a-freeform-assignment?ref=twitter-share)

I recently received a challenge to create something using San Francisco's food truck open [dataset](https://data.sfgov.org/Economy-and-Community/Mobile-Food-Facility-Permit/rqzj-sfat/data). It could be anything I want, the goal is just to show some of my skills and share some high-quality code.

The challenge states that the team loves to eat and that they are also a team that loves variety, so they also like to discover new places to eat. For this reason, I think I want to create a web application using React to list all of the Food Trucks by name, address, and food items available. In addition, I would love to create an onClick, that would allow a user to see the location on Google Maps. Based on this information, I know some of the APIs I may need include the following:

* React (it is a frontend application after all)
    
* Google MAPS API
    
* Chakra-UI (I always wanted to try this)
    
* React Router Dom - I know I will need to route to the google maps page somehow.
    

Those are just some of my thoughts. As build this freeform project, I will share how I get through each challenge that arises and share the resources that get me through it.

#### Side note: Ideally, I would want to store my information in a database using Postgresql and use nodejs/express to route through some of the rest API routes. However, due to time constraints, my goal was to upload the CSV file using React and display it.

## Uploading the CSV file into React

I used [WebStylePress](https://www.youtube.com/watch?v=NAXIXN73uqY&ab_channel=WebStylePress) youtube tutorial to upload the CSV file and display it using React. The tutorial guided me to the papaparse module, which made this easier than I expected to display the data. Example below:

```javascript
import React, { useState, useEffect } from "react";
import Data from "./data/Mobile_Food_Facility_Permit.csv";
import Papa from "papaparse";
  
  const [isDataLoading, setDataLoading] = React.useState(false);
  const [data, setData] = useState([]);

    const fetchData = async () => {
    const response = await fetch(Data);
    const reader = response.body.getReader();
    const result = await reader.read();
    const decoder = new TextDecoder("utf-8");
    const csvData = decoder.decode(result.value);
    const parsedData = Papa.parse(csvData, {
      header: true,
      skipEmptyLines: true,
    }).data;
    setData(parsedData || []);
    setDataLoading(false);
  };

  useEffect(() => {
    setDataLoading(true);
    fetchData();
  }, []);

  console.log(data);
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1684957551295/69ab98ca-25aa-4996-af7c-4ef81f6de453.png align="center")

## Adding Pagination

Luckily, I built an application with some pagination before. I was able to use this file to pass in the data, the current page, and the pagesize to render the paginated pages using [lodash](https://www.npmjs.com/package/lodash). Thank goodness for having past projects! 🎉

Below was the result:

```javascript
import _ from "lodash";

export function paginate(items, currentPage, pageSize) {
  const startIndex = (currentPage - 1) * pageSize;
  return (
    _(items)
      .slice(startIndex)
      .take(pageSize)
      .value()
  );
}
```

Added the following to App.js to display the pagination.

```javascript
 const handlePageChange = (pageNum) => {
    setcurrentPage(pageNum);
  };

  const filtered = data;

  if (data && data.length === 0) return <p> There are no data </p>;

  const paginatedTrucks = paginate(data, currentPage, pageSize);

  return (
    <div className="App">
        <Container maxW="2xl" bg="blue.600" centerContent>
          <h1> Showing {data.length} Food Trucks in database.</h1>
          <TableContainer>
            <Table variant="simple" overflow="scroll" size="sm" maxWidth="10">
              <TableCaption>
                <Pagination
                  itemsCount={filtered.length}
                  pageSize={pageSize}
                  onPageChange={handlePageChange}
                  currentPage={currentPage}
                />
              </TableCaption>
              <Thead>
                <Tr>
                  <Th>Name</Th>
                </Tr>
              </Thead>
              <Tbody>
                {paginatedTrucks.length !== 0 &&
                  paginatedTrucks.map((row, index) => (
                    <Tr>
                      <Td >
                        {row.Applicant}
                      </Td>
                    </Tr>
                  ))}
              </Tbody>
            </Table>
          </TableContainer>
        </Container>
    </div>
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1684979947416/34edfdce-933b-4879-969f-2e212942de80.png align="center")

## Adding a Search Bar

This was by far the hardest part and took me a while to get. The goal was to allow a user to filter through the names of this application to show the Name, FoodItems, and Location. I struggled because the data was an array of multiple objects. For some reason, I could not wrap my mind around how I could filter through the data\["Applicant"\] and find the value that matched the search query.

#### First Attempt

I know had to use Object.values and Object.keys to map through the objects in the array to display in the table. I ended up with this solution, which did show the item, but I had to figure out how to show all of them.

```javascript
  const item = props.trucks[0];
  console.log(Object.keys(item).map((key) => console.log(key)));
```

Resources used:

* [Stackoverflow 1](https://stackoverflow.com/questions/65150453/how-to-list-individual-key-values-in-an-object-in-react)
    
* [Stackoverflow 2](https://stackoverflow.com/questions/14810506/map-function-for-objects-instead-of-arrays)
    

FoodTrucks.jsx

```javascript
import React from "react";
export default function FoodTrucks(props) {
  return (
    <>
      {props.trucks.length ? (
        <table className="table">
          <thead>
            <tr>
              {Object.keys(item).map((key) => (
                <th key={key}>{key}</th>
              ))}
            </tr>
          </thead>
          <tbody>
            {props.trucks.map((row, index) => (
              <tr key={index}>
                {Object.values(row).map((key) => (
                  <th key={key}>{key}</th>
                ))}
              </tr>
            ))}
          </tbody>
        </table>
      ) : null}
    </>
  );
}
  return (
    <>
      {props.trucks.length ? (
        <table className="table">
          <thead>
            <tr>
              {Object.keys(item).map((key) => (
                <th key={key}>{key}</th>
              ))}
            </tr>
          </thead>
          <tbody>
            {props.trucks.map((row, index) => (
              <tr key={index}>
                {Object.values(row).map((key) => (
                  <th key={key}>{key}</th>
                ))}
              </tr>
            ))}
          </tbody>
        </table>
      ) : null}
    </>
  );
}
```

I searched all over the web and eventually figured out the answer by using [lodash](https://www.npmjs.com/package/lodash) again. I was able to use the [.map](https://www.geeksforgeeks.org/lodash-_-map-method/#) to get the value for each object and check to see if it matched the searchQuery a user input. Then the lodash.map allows us to pass in a callback function to return the results from the filter. This was the result:

```javascript
  const Search = (searchTerm, limit = 10) => {
    let results = [];
    _.map(data, function filterItem(n) {
      if (n.Applicant.toLowerCase().startsWith(searchTerm.toLowerCase())) {
        results.push(n);
      }
    });
    return results;
  };
```

I am so happy I figured that out!!!! 🤣🎉

## Google Maps

At this point, I have been working on this project for 4 hours, which is a bit longer than I wanted. So I used some resources to get a move on. I used the following [youtube video](https://www.youtube.com/watch?v=iP3DnhCUIsE&ab_channel=MafiaCodes) and honestly, copied the code and pasted it into my project. (If anything I am resourceful, shout out to [@mafiacodes](https://www.youtube.com/@mafiacodes) on Youtube, make sure you subscribe to their channel!!

The goal was to take Google Maps and when a user clicks on the location, it will route them to the map with the location there. For this, I needed to add [Google Maps API](https://www.npmjs.com/package/@react-google-maps/api) / [React Google Maps Api Style Guide](https://react-google-maps-api-docs.netlify.app/), of course, but also [React router dom](https://www.npmjs.com/package/react-router-dom) to show this on a different page.

#### Issues

I ran into an issue with my Marker not showing up on the Google Map. I googled around and found out that it is a known issue and some believe it has to do with React.StrictMode. I ended up importing the MarkerF "@react-google-maps/api" and that appeared to work. I will do more research on why this error occurred, but for now, it will have to do, due to. . .you guessed it. . .time constraints.

Here are the links to the resources I used to resolve the issue:

* [marker-not-showing-react-google-maps-api-on-localhost-next-js](https://stackoverflow.com/questions/72112491/marker-not-showing-react-google-maps-api-on-localhost-next-js)
    
* [github.com/JustFly1984/react-google-maps-api](https://github.com/JustFly1984/react-google-maps-api/issues/3048#issuecomment-1166410403)
    

## Styling:

I wanted to try a new library but also easily be able to update styling so I went with chakra-ui. It was fun to mess around with it for this project. I would love to do more with

## Updating my readme:

I wanted to make sure my readme was 🔥, so I used my favorite [readme template](https://github.com/othneildrew/Best-README-Template) and used this [markdown playground](https://www.makeareadme.com/) to make sure everything was to my liking.

## End Credits

As I said at the beginning of this post, this was simply to get something done in 2-4 hours, ideally, I would want to have a backend using nodejs and SQL as a database. I may attempt this on my own time, just to show how I would go about it or maybe I will try to rebuild it using [nextjs-prisma-postgres](https://vercel.com/guides/nextjs-prisma-postgres) because why not?!?!? haha

Let me know if you would like to see the Github link.

I hope you enjoyed this read and as always I leave you with a song:

#### Song of the day:

<iframe width="100%" height="166" src="https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/1080277975&color=%23ff5500&auto_play=false&hide_related=false&show_comments=true&show_user=true&show_reposts=false&show_teaser=true"></iframe>

{% embed https://soundcloud.com/lauraroymusic/sunrise-1 %}

[Laura Roy](https://soundcloud.com/lauraroymusic) · [Sunrise](https://soundcloud.com/lauraroymusic/sunrise-1)