Using Redux to Fetch from API in the Client
In this article we're going to work on the express endpoint that serves the markdown. By the end of this lesson we'll have our posts displaying again in the client.
We're going to start where we left off in the last article.
If you need to catch up:
git clone https://github.com/lawwantsin/webpack-course.git
cd webpack-course
git checkout redux-client
npm install
Markdown Content API
We're going to need a few new packages. Let's use the same packages that are used in the markdown-with-front-matter-loader
so it will be consistent with the way webpack is doing it.
In our terminal:
npm i marked yaml-front-matter
Now in express.js
, let's import these and fs
. We'll put the attempt in a try
block. This will allow us to bail out if the slug
doesn't match a file in our folders. If fs.readFile
can't find the file, it will return a 404 in the response.
import marked from "marked"
import fs from "fs"
import { loadFront } from "yaml-front-matter"
server.get("/api/articles/:slug", (req, res, next) => {
try {
const site = req.hostname.split(".")[0]
const { slug } = req.params
if (!slug) {
throw new Error("No slug provided")
}
const file = path.resolve(__dirname, `../../data/${site}/${slug}.md`)
fs.readFile(file, "utf8", (err, data) => {
if (err) {
res.status(404).send(err)
return
}
const obj = yaml.loadFront(data)
obj.__content = marked(obj.__content)
res.json(obj)
})
} catch (err) {
res.status(404).json(err)
}
})
If we do find the file. We grab the yaml and the markdown content into the response, matching what we got from our markdown loader. So when we go to the Article component, very little needs to change.
In Article.js
we connect
the store to the component. We spread the object state.content over the Article as props and they line up perfectly:
export default connect(state => ({
...state.content
}))(Article)
Hot Reloading Reducers
In store.js
:
export default initialState => {
const store = createStore(fetchArticle, enhancer)
if (module.hot) {
module.hot.accept("./reducers", () =>
store.replaceReducer(require("./reducers").fetchArticle)
)
}
return store
}
In Sum
We did it. We setup a client API for fetching our posts. You should see it pulling in the Article once the client code loads. It's still not rendering to server tho.
git checkout redux-client-final
Up Next
Now let's do the same for our server side. This is not as hard as some would make it out to be. But it does require an effective use of Promises.