update dom to render results after api request - javascript

SOLVED: by adding this.tasks = resp.data in the functions so that it updates to the new state...
i'm currently working on a simple todo-list app in vuejs and i'm looking for a way to update the dom in a smooth way after doing the api request. The only way i've been able to display the changes directly after they've been made is by putting location.reload() in the response. I've been looking over some examples and guides and people seem to be able to do this with .bind(), but it's not working for me and i'm not content with the page flashing on every change you make.
//deletePost works for displaying changes but i don't want the page to flash on every update
deletePost(id) {
axios.delete(`http://localhost:3000/tasks/${id}`)
.then((resp) => {
console.log(resp.data)
location.reload();
})
.catch((err) => {
console.log(err)
})
},
//this is how i've seen people doing it, but it's not working for me.
updatePost(selected, id) {
axios.put(`http://localhost:3000/tasks/${id}`,{ status: selected } )
.then(function(response){
console.log('saved successfully')
}.bind(this));
}
},
Any ideas?

You shold have an array of tasks in your Vue component. Sending an http request deletes the resource from the server, but not locally. To delete the resource inside your component you'll need to do it in the .then() part for example like this:
data() return {
tasks: []
},
deletePost(id) {
axios.delete(`http://localhost:3000/tasks/${id}`)
.then((resp) => {
console.log(resp.data)
// Here we delete the task from the component locally
// Note that we only want to delete it if the request is successful
let index= this.tasks.find(task => task.id === id)
this.tasks.splice(index,1);
})
.catch((err) => {
console.log(err)
})
},
//this is how i've seen people doing it, but it's not working for me.
updatePost(selected, id) {
axios.put(`http://localhost:3000/tasks/${id}`,{ status: selected } )
.then(function(response){
console.log('saved successfully')
}.bind(this));
}
},

Thanks for replying to my first post here so quickly, of course i should've provided the whole script and not just the api request...
data () {
return {
tasks: [],
formValue: '',
selected: ''
}
},
created () {
this.fetchData()
},
watch: {
'$route': 'fetchData',
},
methods: {
fetchData () {
axios.get('http://localhost:3000/tasks')
.then((resp) => {
this.tasks = resp.data
console.log(resp.data)
})
.catch((err) => {
console.log(err)
})
},
deletePost(id) {
axios.delete(`http://localhost:3000/tasks/${id}`)
.then((resp) => {
console.log(resp.data)
// Here we delete the task from the component locally
// Note that we only want to delete it if the request is successful
let index= this.tasks.find(task => task.id === id)
this.tasks.splice(index,1);
})
.catch((err) => {
console.log(err)
})
},
//updates post status
updatePost(selected, id) {
axios.put(`http://localhost:3000/tasks/${id}`,{ status: selected } )
.then(function(response){
console.log('saved successfully')
}.bind(this));
}
},
}

Related

Vue JS console logging return an Observer

Here how are my datas in the store :
Here my code :
fetchNotifications() {
let notifications = {}
axios.get('/api/unreadNotifications')
.then(response => {
notifications = response.data
if(notifications) {
this.$store.commit("updateNotifications", notifications)
}
})
.catch(error => {
console.log()
});
},
checkDisplayQuestionnaire() {
console.log(this.$store.state.notifications)
},
If i console.log(response.data) in the .then of fetchNotifications(), datas are like this :
I tried to use JSON.parse(JSON.stringify(this.$store.state.notifications)) without success.
Anyone have an idea of the problem ? Thanks you.

How to reload a GET request in created . Vue.js

i am getting the data from my rails API backend and what i want to do is reload that get request every 15s , so if something changes on a backend ( for example i make a post request to my backend in another route) it reloads and gets the current data .
My created :
created() {
if (!localStorage.signedIn) {
this.$router.replace("/");
} else {
this.$http.secured
.get("/api/v1/records")
.then(response => {
console.log(response.data);
this.records.splice(0, this.records.length - 1, ...response.data);
})
.catch(error => this.setError(error, "Something went wrong"));
this.$http.secured
.get("/api/v1/templates")
.then(response => {
this.templates = response.data;
})
.catch(error => this.setError(error, "Something went wrong"));
this.$http.secured
.get("/api/v1/data")
.then(response => {
this.datas = response.data;
})
.catch(error => this.setError(error, "Something went wrong"));
}
},
Could you help me with implementing a setInterval to my get requests?
thanks
Try to use the setInterval, like:
mounted() {
this.intervalData = setInterval(this.getdata, 15000)
},
destroyed() {
clearInterval(this.intervalData)
},
methods: {
getData() {}
},
More smart solution could be: use POST request in nuxt proxy server or in your backend, like axios.post('/data', payload) and connect the websockets, you can use pusher for that. The final logic is: user add some data => post to server => server emits the websockets event => vuex listen to the event and the data will be reactive in all tabs.

How to delete data from database and UI using react.js and axios?

I am trying to delete data from my app both in the database and UI, but I am a
bit confused on how to request this action from react.js using axios. I have
created a method call which I assigned to an event handler on the elements
'delete' button within my react app but continue to get a message of 'null' in
the terminal. I suppose this is the app telling me that it cannot find the
element I am trying to delete and would greatly appreciate it if someone could
point me in the right direction or give me some pointers on how to fix errors I
may have made along the way.
Below is my react code
state = {
title: '',
body: '',
posts: []
}
deleteBlogPosts = () => {
axios.delete(`/api/delete`)
.then((response) => {
console.log(`${response} request deleted`)
})
.catch((err) => {
console.log(err.response)
})
}
displayBlogPosts = (posts) => {
if(!posts.length) return null
return posts.map((post, index) => (
<div className='blog' key={index}>
<h1>{post.title}</h1>
<h5>{post.body}</h5>
<button onClick={this.deleteBlogPosts()}>delete</button>
</div>
))
}
MY API file with the endpoints
router.delete('/delete', (req, res) => {
Blog.findOneAndRemove({
_id: req.params.Id
}, (err, data) => {
console.log(data)
if(err) {
res.status(500).json({
msg: 'Houston we have a problem'
})
return
}return res.json({
msg: 'Data was received'
})
})
})
Hey everyone thanks for those who attempted to help. Shortly after posting, I realized that I had unnecessary parameters within my 'delete' endpoint. I also found out that I failed to include the ID in the endpoint URL. SO happy that I got it taken care of.

How can I handle a vuex dispatch response?

I'm raising the white flag and asking for suggestions even though I feel the answer is probably right in front of my face.
I have a login form that I am submitting to an api (AWS) and acting on the result. The issue I am having is once the handleSubmit method is called, I am immediately getting into the console.log statement... which to no surprise returns dispatch result: undefined
I realize this is likely not a direct function of vue.js, but how I have the javascript set executing.
Here is my login component:
// SignInForm.vue
handleSubmit() {
try {
const {username, password} = this.form;
this.$store.dispatch('user/authenticate', this.form).then(res => {
console.log('dispatch result: ', res);
});
} catch (error) {
console.log("Error: SignInForm.handleSubmit", error);
}
},
...
Here is what my store is doing. I'm sending it to a UserService I've created. Everything is working great. I am getting the correct response(s) and can log everything out I need. The UserService is making an axios request (AWS Amplify) and returning the response.
// user.js (vuex store)
authenticate({state, commit, dispatch}, credentials) {
dispatch('toggleLoadingStatus', true);
UserService.authenticate(credentials)
.then(response => {
dispatch('toggleLoadingStatus', false);
if (response.code) {
dispatch("setAuthErrors", response.message);
dispatch('toggleAuthenticated', false);
dispatch('setUser', undefined);
// send error message back to login component
} else {
dispatch('toggleAuthenticated', true);
dispatch('setUser', response);
AmplifyEventBus.$emit("authState", "authenticated");
// Need to move this back to the component somehow
// this.$router.push({
// name: 'dashboard',
// });
}
return response;
});
},
...
Where I'm getting stuck at is, if I have error(s) I can set the errors in the state, but I'm not sure how to access them in the other component. I've tried setting the data property to a computed method that looks at the store, but I get errors.
I'm also struggling to use vue-router if I'm successfully authenticated. From what I've read I really don't want to be doing that in the state anyway -- so that means I need to return the success response back to the SignInForm component so I can use vue-router to redirect the user to the dashboard.
Yep. Just took me ~6 hours, posting to SO and then re-evaluating everything (again) to figure it out. It was in fact, somewhat of a silly mistake. But to help anyone else here's what I was doing wrong...
// SignInForm.vue
async handleSubmit() {
try {
await this.$store.dispatch("user/authenticate", this.form)
.then(response => {
console.log('SignInForm.handleSubmit response: ', response); // works
if (response.code) {
this.errors.auth.username = this.$store.getters['user/errors'];
} else {
this.$router.push({
name: 'dashboard',
});
}
}).catch(error => {
console.log('big problems: ', error);
});
} catch (error) {
console.log("Error: SignInForm.handleSubmit", error);
}
},
...
Here's my first mistake: I was calling from an async method to another method - but not telling that method to be async so the call(er) method response was executing right away. Here's the updated vuex store:
// user.js (vuex store)
async authenticate({state, commit, dispatch}, credentials) { // now async
dispatch('toggleLoadingStatus', true);
return await UserService.authenticate(credentials)
.then(response => {
console.log('UserService.authenticate response: ', response); // CognitoUser or code
dispatch('toggleLoadingStatus', false);
if (response.code) {
dispatch("setAuthErrors", response.message);
dispatch('toggleAuthenticated', false);
dispatch('setUser', undefined);
} else {
dispatch('toggleAuthenticated', true);
dispatch('setUser', response);
AmplifyEventBus.$emit("authState", "authenticated");
}
return response;
});
},
...
My second error was that I wasn't returning the result of the method at all from the vuex store.
Old way:
UserService.authenticate(credentials)
Better way:
return await UserService.authenticate(credentials)
Hope this saves someone a few hours. ¯_(ツ)_/¯
This works for Vue3:
export default {
name: 'Login',
methods: {
loginUser: function () {
authenticationStore.dispatch("loginUser", {
email: 'peter#example.com',
})
.then(response => {
if (response.status === 200) {
console.log('Do something')
}
});
},
},
}
In the store you can simply pass back the http response which is a promise.
const authenticationStore = createStore({
actions: {
loginUser({commit}, {email}) {
const data = {
email: email
};
return axios.post(`/authentication/login/`, data)
.then(response => {
toastr.success('Success')
return response
})
},
}
})

Why fetch isn't working second time?

This is a very very annoying thing, i'm trying to solve it for hours right now. Here's the code:
//ExpressJS code
app.post('/newname', (req, res) => {
const {name, type, id} = req.body;
console.log(name, type, id)
knex('fl').insert({
name, type, id,
...type === 'category'? {timeValue: req.body.timeValue, timeType: req.body.timeType} : {}
})
.then(() => {
console.log("bar");
return knex('fl').select('*').where('status', 'available')})
.then(data => res.json(data))
.catch(err => console.log(err))
})
//React code
possibleName = (event) => {
this.setState({
possibleName: event.target.value
})
console.log(this.state.possibleName)
}
complete = () => {
if(Boolean(this.state.possibleName)){
console.log(this.state.possibleName)
fetch('http://localhost:3001/newname', {
method: 'post',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
name: this.state.possibleName,
type: this.state.type,
id: this.props.id,
...this.state.type === 'category'? {timeValue: this.props.timeValue, timeType: this.props.timeType}:{}
})
})
.then(res => res.json())
.then(data => {
console.log("foo");
this.props.dispatch(getAction(data));
this.setState({
create: 'none',
zindex: 0,
possibleName: ''
})
})
.catch(err => console.log(err))
}
}
//...
//...
<input type='text' value={this.state.possibleName} onChange={this.possibleName}/>
<div onClick={this.complete}></div>
So... The first time the div is clicked, everything works fine. All the logs are in the console. The second time, the complete()'s first log happens, but it seems like the fetch isn't happening. What's the reason? Something blocks the second fetch? If i try it with Postman, with the same format of req.body, everything works fine every time i try it. So i don't know what will be the problem.
Another thing that might the source of the problem i think, is that there's a dispatch. It's possible that redux don't let the fetch to finish? I mean the first fetch begins, but not completes, so if i fetch second time, it get into query, and starts when the fetch before finishes?

Categories

Resources