I have a blog application, with a Blog and a User model, both with references to one another. A User has a one to many relationship with Blog model. I need to display a full list of blogs on a Blogs page and a full list of users on a Users page.
If a logged user creates a blog post, my action creator from my Blogs reducer saves the blog to the database, and updates the BLOGS state. My post call to the back-end is saving the blog post AND the user data to the database but i don't have any actions in my User reducer file to update the user state.
On my app's initial render, i load all of the users and the blogs.
Thus my inital store's state upon user login looks like this:
LOGGED_USER
BLOGS
USERS
I am trying to update the state of the User associated with the new Blog post, but having difficulty in figuring out how to do so. I was thinking that I might have to reach into the shared store for the Blogs state in the update User action creator.
EDIT/UPDATE i realized that if i try to call an action creator to update the state of the blog, and then another separate one to call to update the state of the user, with the new blog, i start running into the potential of mismatched id's, since when a new blog post it is auto generating an ID. Thus i think (but could very well be wrong) that i do need to make a call to the store to pickup the updated blog state when trying to update the user.
SO, it would go like this:
CREATE BLOG POST FORM ON FRONT END with NEW BLOG CONTENT with addBlog handler
const addBlog = async event => {
event.preventDefault();
const blogObject = {
url: newURL.value,
title: newTitle.value,
author: newAuthor.value
};
await props.createBlog(blogObject);
await props.updateUser(props.loggedUser, blogObject);
props.history.push("/blogs");
setNotification(`New Blog Created!`, 4);
};
CALL createBlog and updateUser action creators from my blogReducer and User Reducer files:
blogReducer.js
const blogReducer = (state = [], action) => {
switch (action.type) {
case "NEW_BLOG":
return [...state, action.data];
export const createBlog = content => {
return async dispatch => {
const newBlog = await blogService.create(content);
dispatch({
type: "NEW_BLOG",
data: newBlog
});
};
};
userReducer.js
**export const updateUser = (id, blog) => {
return async dispatch => {
dispatch({
type: "UPDATE_USER",
data: {
id: id,
data: blog
}
});
};
};**
const userReducer = (state = [], action) => {
switch (action.type) {
case "NEW_USER":
return [...state, action.data];
case "UPDATE_USER":
const {blogs} = store.getState().blogReducer.blogs
const username = action.data.id.username;
console.log("Action Data", action.data);
const userToChangeBlogs = blogs.find(a => a.user.username === username);
console.log("User to Change", userToChange);
const changedUser = userToChangeBlogs.blogs.concat(action.data.data);
console.log("Change User", changedUser);
return state.map(user =>
user.username !== username ? user : changedUser
);
case "DELETE_USER":
const removeObject = action.data;
return state.filter(user => user.id !== removeObject.id);
case "INIT_USERS":
return action.data;
default:
return state;
}
};
yet as i start to work on this updateUser action creator, i'm stumbling as to how to handle this. ok, so i get the blogs state from the store, grab the username from the person who sent the new blog form and the new blog content. Then i'm looking in the blogs store state for that user from the submitted form
....and then i DO WHAT...i've reached a dead end! Do i just reach into that users state and replace with all of the updated blogs from the blogs store?
I feel LIKE i am making this way more complicated than it needs to be.