Archive Commit
This commit is contained in:
84
instructions/README3.md
Normal file
84
instructions/README3.md
Normal file
@@ -0,0 +1,84 @@
|
||||
# Building Out The Backend
|
||||
## Handling the File Upload
|
||||
1. In the `app.js` file, add multer as a dependency and configure it to store files in a memory buffer.
|
||||
```js
|
||||
const multer = require('multer')
|
||||
|
||||
const storage = multer.memoryStorage()
|
||||
const upload = multer({ storage: storage })
|
||||
```
|
||||
2. Add a new route to the app that will handle the file upload. (This should match the path from the frontend)
|
||||
```js
|
||||
app.post('/api/upload', (req, res) => {
|
||||
console.log(req.file)
|
||||
res.send("File Uploaded")
|
||||
})
|
||||
```
|
||||
3. The above route will log the file object to the terminal. We can use this to make sure the file is being uploaded correctly. We then close the connection with the client by sending a response of "File Uploaded". The challenge is however that `req.file` is undefined. This is because we haven't added the `upload.single('file')` middleware to the route. We will do this in the next step.
|
||||
4. Add the `upload.single('file')` middleware to the route. This will parse the file from the request body and store it in `req.file` for us anytime a file is included in a request to that route. This is why middleware is so great, it allows for simplistic extensibility.
|
||||
```js
|
||||
app.post('/api/upload', upload.single('file'), (req, res) => { ...})
|
||||
```
|
||||
4. You can now test the route by selecting a file in the frontend and clicking the "Upload CSV" button. You should see the file object logged in the terminal of your server.
|
||||
|
||||
## Making Sense of the CSV File
|
||||
1. When we upload a file, we get a file object back. This object contains a lot of information about the file, including the file name, the file type, and the file size. It also contains a buffer that contains the actual contents of the file. We can use the buffer to read the contents of the file.
|
||||
2. Read the buffer and convert it to a string. We can do this by using the `toString()` method on the buffer. The 'utf8' argument tells the method to convert the buffer to a string using the utf8 encoding. (as opposed to ascii, base64, etc.)
|
||||
```js
|
||||
const csvString = req.file.buffer.toString('utf8')
|
||||
```
|
||||
3. We can now log csvString to the terminal to see the contents of the file. You should see a string that contains the contents of the file (all our transactions represented as a string).
|
||||
|
||||
## Adding a Little Error Handling
|
||||
1. You may end up accidentally not selecting a file when you click the "Upload CSV" button. This will cause the server to crash because `req.file` will be undefined. We can add a little error handling to prevent this from happening.
|
||||
2. Add an if statement to the route that checks if `req.file` is undefined. If it is, send a message to the client.
|
||||
```js
|
||||
if (!req.file) {
|
||||
res.status(400).send("No file uploaded")
|
||||
}
|
||||
```
|
||||
|
||||
## Setting up Our Sorting Magic
|
||||
1. Because we will have a lot of logic for sorting the transactions, we will create a new file to handle this. Create a new file called `sortTransactions.js` in the root directory next to app.js
|
||||
2. In the `sortTransactions.js` file, export a default function that takes a string and an array as an argument. This string will be the contents of the csv file and the array will be the list of categories.
|
||||
```js
|
||||
export default function (transactions, categories) {
|
||||
// logic to sort transactions
|
||||
}
|
||||
```
|
||||
3. For now just return a string that says "Hello World". We will add the logic later.
|
||||
4. Import the `sortTransactions` function into the `app.js` file.
|
||||
```js
|
||||
import sortTransactions from './sortTransactions.js'
|
||||
```
|
||||
6. You may notice this import looks a little different than the ones we have been using. This is because we are using ESM imports. This is the new standard for importing modules in JavaScript. You can read more about it [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import). It is also what we have been using in the frontend but it's a recent addition to Node which used to only support CommonJS imports. You can read more about that [here](https://nodejs.org/api/modules.html#modules_modules_commonjs_modules).
|
||||
7. Refactor your imports to use ESM imports.
|
||||
```js
|
||||
import express from 'express'
|
||||
import multer from 'multer'
|
||||
import sortTransactions from './sortTransactions.js'
|
||||
```
|
||||
8. Call the `sortTransactions` function in the route and pass in the csvString and the categories array. Go ahead and hardcode the categories array for now.
|
||||
```js
|
||||
const sortedTransactions = sortTransactions(csvString, ['Bills', 'Groceries', 'Restaurants', 'Entertainment', 'Shopping', 'Travel'])
|
||||
```
|
||||
9. Return the sortedTransactions to the client.
|
||||
```js
|
||||
res.send(sortedTransactions)
|
||||
```
|
||||
|
||||
|
||||
// Not shared below this line
|
||||
Notes:
|
||||
- Migrate to app.js to use ESM Imports
|
||||
- Add "type": "module" to package.json
|
||||
- Use neat-csv to parse csv to json onject
|
||||
- Need to make a [__dirname](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c#what-do-i-use-instead-of-__dirname-and-__filename) variable to get the path to the static folder
|
||||
|
||||
Add to frontend/src/App.jsx to see the return response.
|
||||
```js
|
||||
.then((response) => response.json())
|
||||
.then((data) => {
|
||||
console.log(data);
|
||||
})
|
||||
```
|
||||
Reference in New Issue
Block a user