3D model renderer component not loading file - node.js

I'm working on a feature for a web app I'm developing that consists in a .obj model viewer. The thing is that I don't really know how to work with the three.js library so I decided to go with a dependency to do the trick, I'm using this one. Basically what I'm doing is to get the content of the file in the redux state which is initially obtained by a backend request, so, I ultimately use the state variable and pass it a component prop to the <OBJModel /> component, but I get this error when trying to load:
https://pasteboard.co/Jtdkigq.png
https://pasteboard.co/JtdkPoRk.png
This is the front-end code:
import React from 'react';
import { OBJModel } from 'react-3d-viewer';
import { connect } from 'react-redux';
import { getModel } from './../../actions';
import golem from './../../Stone.obj';
class ModelViewer extends React.Component {
componentDidMount() {
document.querySelector('#upload-modal').style.display = 'flex';
let id = '';
let slashCounter = 0;
for (let i = 0; i < window.location.pathname.length; i++) {
if (slashCounter === 2) {
id = id + window.location.pathname[i];
}
if (window.location.pathname[i] === '/') {
slashCounter++;
}
}
this.props.getModel(id);
}
render() {
if (this.props.model.previewModel)
console.log(this.props.model.previewModel);
return (
<div style={{ display: 'flex', justifyContent: 'center' }}>
{!this.props.model.previewModel ? null : (
<OBJModel
height="500"
width="500"
position={{ x: undefined, y: -5, z: undefined }}
src={this.props.model.previewModel}
/>
)}
<div id="upload-modal" className="upload-modal">
<div className="upload-modal-content">
<p className="upload-modal-header">
<i
className="exclamation circle icon"
style={{ color: 'gray' }}
/>
Loading model...
</p>
<div
className="ui indicating progress active progress-indicator"
id="upload-bar-indicator"
>
<div className="bar" id="upload-bar">
<div className="progress" id="modal-upload-progress"></div>
</div>
</div>
</div>
</div>
</div>
);
}
}
const mapStateToProps = (state) => {
return { model: state.model };
};
export default connect(mapStateToProps, { getModel })(ModelViewer);
This is the action function that makes the request to the backend:
export const getModel = (id) => {
return async (dispatch) => {
const config = {
onDownloadProgress: function (progressEvent) {
let percentCompleted = Math.round(
(progressEvent.loaded * 100) / progressEvent.total
);
document.querySelector(
'#modal-upload-progress'
).innerHTML = `${percentCompleted}%`;
document.querySelector(
'#upload-bar'
).style.width = `${percentCompleted}%`;
document
.querySelector('#upload-bar-indicator')
.setAttribute('data-percent', `${percentCompleted}`);
},
};
const response = await axios.get(
`https://hushpuppys-3d-hub-api.herokuapp.com/api/v1/modelfiles/${id}.obj`,
config
);
document.querySelector('#upload-modal').style.display = 'none';
dispatch({ type: 'GET_MODEL', payload: response.data.data });
};
};
This is the controller that downloads the file from the Cloud Storage where im storing the files:
exports.fileDownloaderController = async (req, res) => {
try {
const fileName = req.params.id;
const config = {
headers: { Authorization: credentials.authorizationToken },
};
await axios
.get(
`${credentials.downloadUrl}/file/hushpuppys-3d-hub-storage/${fileName}`,
config
)
.then(function (response) {
console.log(response.data);
res.status(200).json({
status: 'success',
data: response.data,
});
})
.catch(function (err) {
console.log(err); // an error occurred
});
} catch (err) {
console.log(err);
res.status(404).json({
status: 'fail',
message: err.message,
});
}
};
And this is how the downloaded files look like when they are downloaded from the server, and logged in the console:
https://pasteboard.co/JtdpMCi.png

Related

Builds a chat app in React, using axios and firestore

Please I would be happy if anyone would help me
I have a problem, I can not use the server-side functions, I call the functions with axios, and execute it in react hooks.
I actually build chat, which is why I use react hook, because I want messages to be updated all the time.
I also use firestore. There I save the messages, and receive them through the server side function.
It's a component of the chat - it's causing me problems, I do not understand why.
The server side functions work great, I tested them in postman, and they worked. The problem is that I can't run them in a function component. I do not know what I'm doing wrong.
The error I get here is in the line chat.users.length> 0?, When I make this comparison I get that chat.users is undefined, but I do not understand why because I initialize it at first, using a server side function , Which gives the necessary information
I'm very confused, and I'm new here on the site, I'm trying to figure out why it has not worked for two whole days
I think I might be confused by syntax, for example using an unnecessary dispatch inside component of the chat
i got this error:
enter image description here
component of the chat
import React, { useEffect, useState } from 'react';
import './style.css';
import { useDispatch, useSelector } from 'react-redux';
import { getRealtimeUsers, updateMessage, getRealtimeConversations } from '../../redux/actions/chatActions';
import { Fragment } from 'react';
const User = (props) => {
const { chat, onClick } = props;
return (
<div onClick={() => onClick(chat)} className="displayName">
<div className="displayPic">
<img src="https://i.pinimg.com/originals/be/ac/96/beac96b8e13d2198fd4bb1d5ef56cdcf.jpg" alt="" />
</div>
<div style={{ display: 'flex', flex: 1, justifyContent: 'space-between', margin: '0 10px' }}>
<span style={{ fontWeight: 500 }}>{chat.firstName} {chat.lastName}</span>
<span className={chat.isOnline ? `onlineStatus` : `onlineStatus off`}></span>
</div>
</div>
);
}
const HomePage = (props) => {
const dispatch = useDispatch();
const user = useSelector(state => state.user.credentials);
const chat = useSelector(state => state.chat);
const [chatStarted, setChatStarted] = useState(false);
const [chatUser, setChatUser] = useState('');
const [message, setMessage] = useState('');
const [userUid, setUserUid] = useState(null);
let unsubscribe;
useEffect(() => {
//unsubscribe = dispatch(getRealtimeUsers(user.handle))
dispatch(getRealtimeUsers());
}, []);
//console.log(user);
//componentWillUnmount
useEffect(() => {
return () => {
//cleanup
//unsubscribe.then(f => f()).catch(error => console.log(error));
unsubscribe.then(f => f()).catch(error => console.log(error));
}
}, []);
//function
const initChat = (chat) => {
setChatStarted(true)
setChatUser(`${chat.firstName} ${chat.lastName}`)
setUserUid(chat.handle);
console.log(chat);
dispatch(getRealtimeConversations({ uid_1: user.handle, uid_2: chat.handle }));
}
const submitMessage = (e) => {
const msgObj = {
user_uid_1: user.handle,
user_uid_2: userUid,
message
}
if (message !== "") {
dispatch(updateMessage(msgObj))
.then(() => {
setMessage('')
});
}
//console.log(msgObj);
}
return (
<Fragment>
<section className="container">
<div className="listOfUsers">
{console.log(chat)}
{
//chat.users != undefined
chat.users.length > 0 ?
chat.users.map(user => {
return (
<User
onClick={initChat}
key={user.handle}
user={user}
/>
);
})
: null
}
</div>
<div className="chatArea">
<div className="chatHeader">
{
chatStarted ? chatUser : ''
}
</div>
<div className="messageSections">
{
chatStarted ?
chat.conversations.map(con =>
<div style={{ textAlign: con.user_uid_1 == user.handle ? 'right' : 'left' }}>
<p className="messageStyle" >{con.message}</p>
</div>)
: null
}
</div>
{
chatStarted ?
<div className="chatControls">
<textarea
value={message}
onChange={(e) => setMessage(e.target.value)}
placeholder="Write Message"
/>
<button onClick={submitMessage}>Send</button>
</div> : null
}
</div>
</section>
</Fragment>
);
}
export default HomePage;
This is the axios:
app.get('/realtimeUsers', FBAuth, getRealtimeUsers );
app.post('/updateMessage', FBAuth, updateMessage);
app.get('/realtimeConversations', FBAuth, getRealtimeConversations);
And this is the server side functions - They work 100% - I checked them many times and they worked.:
const { db } = require('../util/admin');
exports.getRealtimeUsers = (req, res) => {
db.collection("users")
.onSnapshot((querySnapshot) => {
const users = [];
querySnapshot.forEach(function (doc) {
if (doc.data().handle != req.user.handle) {
users.push(doc.data());
}
});
return res.json(users);
});
}
exports.updateMessage = (req, res) => {
db.collection('conversations')
.add({
...req.body,
isView: false,
createdAt: new Date()
})
.then(() => {
return res.json({ message: "Conversations added successfully" });
})
.catch((err) => {
console.error(err);
return res.status(500).json({ error: err.code });
});
}
exports.getRealtimeConversations = (req, res) => {
console.log(JSON.stringify("testing"));
console.log(JSON.stringify(req.query));
console.log(JSON.parse(req.query.user));
console.log(JSON.parse(req.query.user).uid_1);
console.log(JSON.parse(req.query.user).uid_2);
db.collection('conversations')
.where('user_uid_1', 'in', [JSON.parse(req.query.user).uid_1, JSON.parse(req.query.user).uid_2])
.orderBy('createdAt', 'asc')
.onSnapshot((querySnapshot) => {
const conversations = [];
querySnapshot.forEach(doc => {
console.log(JSON.stringify(doc));
if (
(doc.data().user_uid_1 == JSON.parse(req.query.user).uid_1 && doc.data().user_uid_2 == JSON.parse(req.query.user).uid_2)
||
(doc.data().user_uid_1 == JSON.parse(req.query.user).uid_2 && doc.data().user_uid_2 == JSON.parse(req.query.user).uid_1)
) {
conversations.push(doc.data())
}
});
console.log(conversations);
return res.json(conversations);
})
//return res.json([]);
}
this is the actions that used in the client side, here i call to the axios:
import { userConstants } from "../types";
import axios from 'axios';
export const getRealtimeUsers = () => (dispatch) => {
dispatch({ type: `${userConstants.GET_REALTIME_USERS}_REQUEST` });
axios
.get('/realtimeUsers')
.then((res) => {
console.log(res);
dispatch({
type: `${userConstants.GET_REALTIME_USERS}_SUCCESS`,
payload: res.data
});
})
.catch((err) => console.log(err))
}
export const updateMessage = (msgObj) => (dispatch) => {
axios.post('/updateMessage', msgObj)
.then(() => { })
.catch((err) => console.log(err));
}
export const getRealtimeConversations = (user) => (dispatch) => {
//user = { uid_1: "from visualcode", uid_2: "userUid" };
console.log(JSON.stringify(user));
axios.get('/realtimeConversations',
{
params: {
user: JSON.stringify(user)
//uid_1:JSON.stringify("user.handle"),
//uid_2:JSON.stringify("userUid")
}
}
)
.then((res) => {
dispatch({
type: userConstants.GET_REALTIME_MESSAGES,
payload: res.data
});
})
.catch((err) => console.log(err))
}
I am not able to understand your whole code flow, i.e., how the chat.users will be populated before initChat is called.
But still, for your problem, you should always put a check for undefined values while iterating through an array.
<div className="listOfUsers">
{console.log(chat)}
{
//chat.users != undefined
chat && chat.users && chat.users.length > 0 &&
chat.users.map(user => {
return (
<User
onClick={initChat}
key={user.handle}
user={user}
/>
);
})
}
</div>

_id is missing after doing actions

i'm currently creating my first MERN App, and everything is going well, until something happened, and i'm going my try to explain because i need help !
What i'm doing is a facebook clone, where you can post something, you can delete your post and you can update your post, the logic is simple, i call dispatch to pass the data to the actions, the actions pass the data to the backend, and the backend return something to me and it saves in my store, because i'm using redux
The problem is that, when i have 2 post, and i want to delete a post, or maybe i want to edit it, the other post dissapears, it's like it loses its id and then loses the information, then i can't do anything but reaload the page, and it happens always
this is how it looks like, everything fine
Then, after trying to edit a post, the second one lost its information, and in the console, it says that Warning: Each child in a list should have a unique "key" prop, and i already gave each post the key={_id}, but the post lost it and i don't know how
Here's the code
Posts.js
import React, { useState } from "react";
import "./Posts.css";
import moment from "moment";
// Icons
import { BiDotsVertical, BiLike } from "react-icons/bi";
import { MdDeleteSweep } from "react-icons/md";
import { AiFillLike } from "react-icons/ai";
import { GrClose } from "react-icons/gr";
// Calling actions
import { deletePost, } from "../actions/posts.js";
// Gettin The Data From Redux
import { useSelector, useDispatch } from "react-redux";
const Posts = ({ setCurrentId }) => {
const [animation, setAnimation] = useState(false);
const [modal, setModal] = useState(false);
const [modalPost, setModalPost] = useState({});
// Getting The Posts
const posts = useSelector(state => state.posts);
const dispatch = useDispatch();
// Showing And Hiding Modal Window
const ModalWindow = post => {
setModalPost(post);
setModal(true);
};
// Liking the post
// const Like = id => {
// dispatch(giveLike(id));
// setAnimation(!animation);
// };
if (!posts.length) {
return <div>Loading</div>;
} else {
return (
<div className="Posts">
{/* // Modal window for better look to the post */}
{/* {modal && (
<div className="modalWindow">
<div className="container">
<div className="container-image">
<img src={modalPost.image} alt="" />
</div>
<div className="information">
<div className="container-information">
<div className="data-header">
<h2>
User <br />{" "}
<span style={{ fontWeight: "400" }}>
{moment(modalPost.createdAt).fromNow()}
</span>
</h2>
<span className="data-icon" onClick={() => setModal(false)}>
<GrClose />
</span>
</div>
<div className="message">
<h2>{modalPost.title}</h2>
<p>{modalPost.message}</p>
</div>
</div>
</div>
</div>
</div>
)} */}
{/* */}
{posts.map(post => {
const { _id, title, message, image, createdAt, likes } = post;
return (
<div className="Posts-container" key={_id}>
<div className="Fit">
<div className="Fit-stuff">
<h2 className="Fit-stuff_title">
User <br />{" "}
<span style={{ fontWeight: "400" }}>
{moment(createdAt).fromNow()}
</span>
</h2>
<a
className="Fit-stuff_edit"
href="#form"
onClick={() => setCurrentId(_id)}
>
<BiDotsVertical />
</a>
</div>
<div className="Fit-data">
<h2 className="Fit-data_title">{title}</h2>
<p className="Fit-data_message">{message}</p>
{image ? (
<div className="Fit-img">
<img
onClick={() => ModalWindow(post)}
src={image}
alt=""
/>
</div>
) : (
<div></div>
)}
</div>
<div className="Fit-shit">
<span>
{animation ? (
<AiFillLike className="fullLightBlue" />
) : (
<BiLike />
)}
{likes}
</span>
<span onClick={() => dispatch(deletePost(_id))}>
<MdDeleteSweep />
</span>
</div>
</div>
</div>
);
})}
</div>
);
}
};
export default Posts;
The form where i call update and create Post
import React, { useState, useEffect } from "react";
import Filebase from "react-file-base64";
// For the actions
import { useDispatch, useSelector } from "react-redux";
import { createPost, updatePost } from "../actions/posts.js";
import {
Wrapper,
FormContainer,
Data,
DataInput,
SecondDataInput,
FormContainerImg,
FormContainerButtons,
Buttons
} from "./FormStyled.js";
const Form = ({ currentId, setCurrentId }) => {
const [formData, setFormData] = useState({
title: "",
message: "",
image: ""
});
const specificPost = useSelector(state =>
currentId ? state.posts.find(p => p._id === currentId) : null
);
// Sending The Data And Editing The data
const dispatch = useDispatch();
useEffect(() => {
if (specificPost) setFormData(specificPost);
}, [specificPost]);
// Clear Inputs
const clear = () => {
setCurrentId(0);
setFormData({ title: "", message: "", image: "" });
};
const handleSubmit = async e => {
e.preventDefault();
if (currentId === 0) {
dispatch(createPost(formData));
clear();
} else {
dispatch(updatePost(currentId, formData));
clear();
}
};
return (
<Wrapper>
<FormContainer onSubmit={handleSubmit}>
<Data>
<DataInput
name="title"
maxLength="50"
placeholder="Title"
type="text"
value={formData.title}
onChange={e => setFormData({ ...formData, title: e.target.value })}
/>
<SecondDataInput
name="message"
placeholder="Message"
maxLength="300"
value={formData.message}
required
onChange={e =>
setFormData({ ...formData, message: e.target.value })
}
/>
<FormContainerImg>
<Filebase
required
type="file"
multiple={false}
onDone={({ base64 }) =>
setFormData({ ...formData, image: base64 })
}
/>
</FormContainerImg>
<FormContainerButtons>
<Buttons type="submit" create>
{specificPost ? "Edit" : "Create"}
</Buttons>
<Buttons onClick={clear} clear>
Clear
</Buttons>
</FormContainerButtons>
</Data>
</FormContainer>
</Wrapper>
);
};
export default Form;
My actions
import {
GETPOSTS,
CREATEPOST,
DELETEPOST,
UPDATEPOST,
LIKEPOST
} from "../actionTypes/posts.js";
import * as api from "../api/posts.js";
export const getPosts = () => async dispatch => {
try {
const { data } = await api.getPosts();
dispatch({ type: GETPOSTS, payload: data });
} catch (error) {
console.log(error);
}
};
export const createPost = newPost => async dispatch => {
try {
const { data } = await api.createPost(newPost);
dispatch({ type: CREATEPOST, payload: data });
} catch (error) {
console.log(error);
}
};
export const updatePost = (id, updatePost) => async dispatch => {
try {
const { data } = await api.updatePost(id, updatePost);
dispatch({ type: UPDATEPOST, payload: data });
} catch (error) {
console.log(error);
}
};
export const deletePost = id => async dispatch => {
try {
await api.deletePost(id);
dispatch({ type: DELETEPOST, payload: id });
} catch (error) {
console.log(error);
}
};
Redux Part
import {
GETPOSTS,
CREATEPOST,
DELETEPOST,
UPDATEPOST,
LIKEPOST
} from "../actionTypes/posts.js";
const postData = (posts = [], action) => {
switch (action.type) {
case GETPOSTS:
return action.payload;
case CREATEPOST:
return [...posts, action.payload];
case UPDATEPOST:
return posts.map(post =>
action.payload._id === post._id ? action.payload : posts
);
case DELETEPOST:
return posts.filter(post => post._id !== action.payload);
default:
return posts;
}
};
export default postData;
My controllers in the backend
import mongoose from "mongoose";
import infoPost from "../models/posts.js";
// Getting All The Posts
export const getPosts = async (req, res) => {
try {
const Posts = await infoPost.find();
res.status(200).json(Posts);
} catch (error) {
res.status(404).json({ message: error.message });
console.log(error);
}
};
// Creating A Post
export const createPost = async (req, res) => {
const { title, message, image } = req.body;
const newPost = new infoPost({ title, message, image });
try {
await newPost.save();
res.status(201).json(newPost);
} catch (error) {
res.status(409).json({ message: error.message });
console.log(error);
}
};
// Update A Post
export const updatePost = async (req, res) => {
const { id } = req.params;
const { title, message, image } = req.body;
if (!mongoose.Types.ObjectId.isValid(id))
return res.status(404).send(`No Post With Id Of ${id}`);
const updatedPost = { title, message, image, _id: id };
await infoPost.findByIdAndUpdate(id, updatedPost, { new: true });
res.json(updatedPost);
};
// Deleting A Post
export const deletePost = async (req, res) => {
const { id } = req.params;
if (!mongoose.Types.ObjectId.isValid(id))
return res
.status(404)
.send(`We Couldnt Found The Post With Id Of ${id} To Delete`);
await infoPost.findByIdAndRemove(id);
res.json(`Post With Id Of ${id} Deleted Succesfully`);
};
// Liking A Post
export const likePost = async (req, res) => {
const { id } = req.params;
if (!mongoose.Types.ObjectId.isValid(id))
return res.status(404).send(`No post with id: ${id}`);
const post = await infoPost.findById(id);
const updatedPost = await infoPost.findByIdAndUpdate(
id,
{ likeCount: post.likeCount + 1 },
{ new: true }
);
res.json(updatedPost);
};
Even though i've been trying to solve this problem for nearly 3.5 hours, i think that the problem might be in my Posts.js part, if you can help me, you're the greatest !

how to make API GET call for SpotifyAPI specifically, getUserPlaylists()?

I am trying to make a web application using the Spotify web API.
I used the Spotify auth-server code provided in their GitHub repo for my authorization code https://github.com/spotify/web-api-auth-examples
I followed the instructions here https://medium.com/#jonnykalambay/now-playing-using-spotifys-awesome-api-with-react-7db8173a7b13 to create a simple app that getsCurrentPlayback and displays the songs album art of what is now playing on users Spotify account.
I added a getFeatures function to get the valence of the song.
Right now I want to call the getUsersPlaylists() function from the spotify-web-api.
Once I can get the playlists to call to work I want to iterate through the tracks in the playlist to get each tracks valence. I think once I can get the playlist API call to work I can figure out the rest on my own.
(Help a poor college student out whose teammates don't do anything and who can't get help from the Prof because of COVID)
Thanks so much in advance!
Here is the code for my App.js. I am using REACT
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import Spotify from 'spotify-web-api-js';
const spotifyWebApi = new Spotify();
class App extends Component {
constructor(){
super();
const params = this.getHashParams();
this.state ={
loggedIn: params.access_token ? true : false,
nowPlaying: {
name: "Not Checked",
image: '',
trackId: "",
valence: ""
},
idParams: {
userId: ""
},
playlistParam: {
playlistName: ""
},
myAccessToken: {
token: ""
}
}
if(params.access_token){
spotifyWebApi.setAccessToken(params.access_token);
}
}
getHashParams() {
var hashParams = {};
var e, r = /([^&;=]+)=?([^&;]*)/g,
q = window.location.hash.substring(1);
while ( e = r.exec(q)) {
hashParams[e[1]] = decodeURIComponent(e[2]);
}
return hashParams;
}
getToken() {
return spotifyWebApi.getAccessToken();
}
// Get user Id of logged in account user.
async getUserId(myToken)
{
const headers = {
Authorization: `Bearer ${myToken}`
};
let userId = '';
const response = await fetch('https://api.spotify.com/v1/me/playlists',
{
headers : headers
}
);
const jsonResponse = await response.json();
if(jsonResponse)
{
userId = jsonResponse.id;
}
return userId;
}
//***HERE IS SOME CODE I HAVE TRIED***
//
// fetch("https://api.spotify.com/v1/me/playlists?limit=1&offset=0", {
// headers: {
// Accept: "application/json",
// Authorization: "Bearer",
// "Content-Type": "application/json"
// }
// })
// fetch("https://api.spotify.com/v1/me/playlists", {
// headers: {
// Authorization: "Bearer {params.access_token}"
// //console.log("Have Gotten The Playlist");
// }
// });
//
// getUserPlaylist() {
// fetch("https://api.spotify.com/v1/me/playlists/", {
// headers: {
// Authorization: "Bearer {this.getToken()}"
// }
// });
//
// console.log("Have Completed It");
//
// }
//********
getNowPlaying() {
spotifyWebApi.getMyCurrentPlaybackState()
.then((response) => {
this.setState({
nowPlaying: {
name: response.item.name,
image: response.item.album.images[0].url,
trackId: response.item.id
}
});
})
}
getFeatures(){
spotifyWebApi.getAudioFeaturesForTrack(this.state.nowPlaying.trackId)
.then(
function(data){
console.log("Valence of song: ", data.valence);
},
function(err){
console.log(err)
}
);
}
render(){
return (
<div className="App">
<a href="http://localhost:8888">
<button>Login With Spotify</button>
</a>
<div> Now Playing: { this.state.nowPlaying.name } </div>
<div>
<img src={ this.state.nowPlaying.image } style={{width: 100}}/>
</div>
<div>
Track Id: { this.state.nowPlaying.trackId } </div>
<button onClick={() => this.getNowPlaying()}>
Check Now Playing
</button>
<button onClick={() => this.getFeatures()}>
Get Valence
</button>
<button onClick={() => this.getUserPlaylist()}>
Get your Playlists
</button>
<div> Your Selected Playlist : {this.state.playlistParam.playlistName}</div>
<button onClick={() => console.log(this.getUserId(this.params.access_token))}> Get User Id</button>
</div>
);
}
}
export default App;

How to update the user feed after updating the post?

I have a UserFeed component and EditForm component. As soon as I edit the form, I need to be redirected to the UserFeed and the updated data should be shown on UserFeed(title and description of the post).
So, the flow is like-UserFeed, which list the posts, when click on edit,redirected to EditForm, updates the field, redirected to UserFeed again, but now UserFeed should list the posts with the updated data, not the old one.
In this I'm just redirectin to / just to see if it works. But I need to be redirected to the feed with the updated data.
EditForm
import React, { Component } from "react";
import { connect } from "react-redux";
import { getPost } from "../actions/userActions"
class EditForm extends Component {
constructor() {
super();
this.state = {
title: '',
description: ''
};
handleChange = event => {
const { name, value } = event.target;
this.setState({
[name]: value
})
};
componentDidMount() {
const id = this.props.match.params.id
this.props.dispatch(getPost(id))
}
componentDidUpdate(prevProps) {
if (prevProps.post !== this.props.post) {
this.setState({
title: this.props.post.post.title,
description: this.props.post.post.description
})
}
}
handleSubmit = () => {
const id = this.props.match.params.id
const data = this.state
this.props.dispatch(updatePost(id, data, () => {
this.props.history.push("/")
}))
}
render() {
const { title, description } = this.state
return (
<div>
<input
onChange={this.handleChange}
name="title"
value={title}
className="input"
placeholder="Title"
/>
<textarea
onChange={this.handleChange}
name="description"
value={description}
className="textarea"
></textarea>
<button>Submit</button>
</div>
);
}
}
const mapStateToProps = store => {
return store;
};
export default connect(mapStateToProps)(EditForm)
UserFeed
import React, { Component } from "react"
import { getUserPosts, getCurrentUser } from "../actions/userActions"
import { connect } from "react-redux"
import Cards from "./Cards"
class UserFeed extends Component {
componentDidMount() {
const authToken = localStorage.getItem("authToken")
if (authToken) {
this.props.dispatch(getCurrentUser(authToken))
if (this.props && this.props.userId) {
this.props.dispatch(getUserPosts(this.props.userId))
} else {
return null
}
}
}
render() {
const { isFetchingUserPosts, userPosts } = this.props
return isFetchingUserPosts ? (
<p>Fetching....</p>
) : (
<div>
{userPosts &&
userPosts.map(post => {
return <Cards key={post._id} post={post} />
})}
</div>
)
}
}
const mapStateToPros = state => {
return {
isFetchingUserPosts: state.userPosts.isFetchingUserPosts,
userPosts: state.userPosts.userPosts.userPosts,
userId: state.auth.user._id
}
}
export default connect(mapStateToPros)(UserFeed)
Cards
import React, { Component } from "react"
import { connect } from "react-redux"
import { compose } from "redux"
import { withRouter } from "react-router-dom"
class Cards extends Component {
handleEdit = _id => {
this.props.history.push(`/post/edit/${_id}`)
}
render() {
const { _id, title, description } = this.props.post
return (
<div className="card">
<div className="card-content">
<div className="media">
<div className="media-left">
<figure className="image is-48x48">
<img
src="https://bulma.io/images/placeholders/96x96.png"
alt="Placeholder image"
/>
</figure>
</div>
<div className="media-content" style={{ border: "1px grey" }}>
<p className="title is-5">{title}</p>
<p className="content">{description}</p>
<button
onClick={() => {
this.handleEdit(_id)
}}
className="button is-success"
>
Edit
</button>
</div>
</div>
</div>
</div>
)
}
}
const mapStateToProps = state => {
return {
nothing: "nothing"
}
}
export default compose(withRouter, connect(mapStateToProps))(Cards)
updatePost action
export const updatePost = (id, data, redirect) => {
return async dispatch => {
dispatch( { type: "UPDATING_POST_START" })
try {
const res = await axios.put(`http://localhost:3000/api/v1/posts/${id}/edit`, data)
dispatch({
type: "UPDATING_POST_SUCCESS",
data: res.data
})
redirect()
} catch(error) {
dispatch({
type: "UPDATING_POST_FAILURE",
data: { error: "Something went wrong"}
})
}
}
}
I'm not sure if my action is correct or not.
Here's the updatePost controller.
updatePost: async (req, res, next) => {
try {
const data = {
title: req.body.title,
description: req.body.description
}
const post = await Post.findByIdAndUpdate(req.params.id, data, { new: true })
if (!post) {
return res.status(404).json({ message: "No post found "})
}
return res.status(200).json({ post })
} catch(error) {
return next(error)
}
}
One mistake is that to set the current fields you need to use $set in mongodb , also you want to build the object , for example if req.body does not have title it will generate an error
updatePost: async (req, res, next) => {
try {
const data = {};
if(title) data.title=req.body.title;
if(description) data.description=req.body.description
const post = await Post.findByIdAndUpdate(req.params.id, {$set:data}, { new: true })
if (!post) {
return res.status(404).json({ message: "No post found "})
}
return res.status(200).json({ post })
} catch(error) {
return next(error)
}
}

Data fetching from oracle db and displaying on browser using app.get

I am able to fetch the data from the db and it is displaying on the inspect element also but it is not displaying on the browser i mean UI.
//storing the data into the posts
this.state = {
displayMenu: false,
posts: [ ]
};
//click function for the drop down and handling the axios.get
Click = event => {
event.preventDefault();
let currentComponent = this;
axios.get(`http://localhost:4000/api/AMS`)
.then(function (response) {
console.log(response);
currentComponent.setState({posts: response.data})
})
.catch(function (error) {
console.log(error);
});
}
//Render method
render() {
// var back = {backgroundSize : 'cover'};
var textStyle = {
position: 'absolute',
top: '50%',
left: '50%'
};
//From here the checking of data is happening, if the data is found inside the posts it will show it on the browser otherwise it will show no posts.
const { posts } = this.state;
const postList = posts.length ? (
posts.map(post => {
// console.log('hi');
return (
<div className="post card" key={post.ID}>
<div className="card-content">
</div>
</div>
)
})
) : ( <div className="center">No posts yet</div>)
//RETURN method
return (
<div>
{/* <Image
style={back} responsive
src={logo}>
</Image> */}
<div style={textStyle} className="dropdown" style = {{background:"red",width:"200px"}} >
<div className="button" onClick={this.showDropdownMenu}> Regions </div>
{ this.state.displayMenu ? (
<ul>
<li><a className="active" href="/AMS" onClick={this.Click}>AMS</a></li>
<li>EMEA</li>
<li>APJ</li>
</ul>
):(null)
}
</div>
//Here i am calling the postList variable
{postList}
{/* {this.state.posts}<br/>
{this.state.pictures} */}
</div>
);
}
}
Click = event => {
event.preventDefault();
let currentComponent = this;
axios.get(`http://localhost:4000/api/AMS`)
.then(function (response) {
console.log(response);
currentComponent.setState({posts: response.data})
})
.catch(function (error) {
console.log(error);
});
}
render() {
// var back = {backgroundSize : 'cover'};
var textStyle = {
position: 'absolute',
top: '50%',
left: '50%'
};
const { posts } = this.state;
const postList = posts.length ? (
posts.map(post => {
// console.log('hi');
return (
<div className="post card" key={post.ID}>
<div className="card-content">
</div>
</div>
)
})
) : ( <div className="center">No posts yet</div>)
The results that i am getting in the inspect element console is like below:
ID: 229, EMAIL: "anuraguk3#gmail.com", ROLE: "BASE", PASSWORD:"$2b$10$ShTWYAtF8M5JLhEm68JqTuMx7P8x6dtOIkNsGz4wE21LY92xGoDCO"
DOM is rendered before getting server response.So, you need to use async-await in this scenario. For your program:-
Click = async(event) => {
event.preventDefault();
let currentComponent = this;
await axios.get(`http://localhost:4000/api/AMS`)
.then(function (response) {
console.log(response);
currentComponent.setState({posts: response.data})
})
.catch(function (error) {
console.log(error);
});
}

Resources