Hi All
I have been working through a tutorial article written by Emannuel Ohans on FCC, where we create a skype clone app.
I’m stuck on a section where I’m trying to create a feature that allows me to type text into the chat and update the redux store with the new information, followed by an update on the chat window showing the submitted text as a sent message
For some reason, when I run my code and investigate using console.log, the arguments I put into my dispatch for the
message.js
messages function come out as undefined, NaN and null… could someone please point me in the right direction for debugging?
It’s complicated to show all the different folders here but I hope this is clear enough.
// ...\src\actions\index.js
import {
SET_ACTIVE_USER_ID,
SET_TYPING_VALUE,
SEND_MESSAGE
} from "../constants/action-types";
export const setActiveUserId = id => ({
type: SET_ACTIVE_USER_ID,
payload: id
});
export const setTypeValue = inputValue => ({
type: SET_TYPING_VALUE,
payload: inputValue
});
export const sendMessage = (message, userId) => ({
type: SEND_MESSAGE,
payload: {
message: message,
userId: userId
}
});
// …\src\components\ChatWindow.js
import "./ChatWindow.css";
import React from "react";
import store from "../store";
import Header from "../components/Header";
import Chats from "../components/Chats";
import MessageInput from "../containers/MessageInput";
import _ from "lodash";
const ChatWindow = ({ activeUserId }) => {
const state = store.getState();
const activeUser = state.contacts[activeUserId];
const activeMsgs = state.messages[activeUserId];
const { typing } = state;
return (
<div className="ChatWindow">
<Header user={activeUser} />
<Chats messages={_.values(activeMsgs)}/>
<MessageInput value={typing}/>
</div>
);
};
export default ChatWindow;
// …\src\components\chats.js
import "./Chats.css";
import React, { Component } from "react";
const Chat = ({ message }) => {
const { text, is_user_msg } = message;
return (
<span className={`Chat ${is_user_msg ? "is-user-msg" : ""}`}>{text}</span>
);
};
class Chats extends Component {
render() {
return (
<div className="Chats">
{this.props.messages.map(message => (
<Chat message={message} key={message.number} />
))}
</div>
);
}
}
export default Chats;
// …\src\containers\MessageInput.js
import "./MessageInput.css";
import React from "react";
import store from "../store";
import { sendMessage, setTypeValue } from "../actions";
import { state } from "../static-data";
//supporting functions
// main export
const MessageInput = ({ value }) => {
const handleSubmit = e => {
e.preventDefault();
const { typing, activeUserId } = state;
console.log(typing, activeUserId);
store.dispatch(sendMessage(typing, activeUserId));
};
const handleChange = e => {
store.dispatch(setTypeValue(e.target.value));
};
return (
<form className="Message" onSubmit={handleSubmit}>
<input
className="Message__input"
onChange={handleChange}
value={value}
placeholder="write a message"
/>
</form>
);
};
export default MessageInput;
// …\reducer\index.js.js
import user from "./user";
import contacts from "./contacts";
import activeUserId from "./activeUserId";
import messages from "./messages";
import typing from "./typing";
import { combineReducers } from "redux";
export default combineReducers({
user,
messages,
typing,
contacts,
activeUserId
})
// …\reducer\messages.js
import { getMessages } from "../static-data";
import { SEND_MESSAGE } from "../constants/action-types";
import _ from "lodash";
export default function messages(state = getMessages(10), action) {
switch (action.type) {
case SEND_MESSAGE:
const message = action.payload.message;
const userId = action.payload.userId;
const allUserMsgs = state[userId];
const number = 10;
console.log(message, userId, allUserMsgs, number, "test");
return {
...state,
[userId]: {
...allUserMsgs,
[number]: {
number,
text: message,
is_user_msg: true
}
}
}
default:
return state;
}
}
// …\reducer\typing.js
import { SET_TYPING_VALUE } from "../constants/action-types";
export default function typing(state = "", action) {
switch(action.type) {
case SET_TYPING_VALUE:
return action.payload;
default:
return state;
}
}
// …\store\index.js
import {createStore} from "redux";
import reducer from "../reducer/index";
const store = createStore(reducer);
export default store;