How to update value to firebase database with Angular 5 - javascript

I would like to make an upvote function. I have some posts stored in database with Firebase. I would like to let people upvote (or downvote) for a post.
Here is in my ctrl :
upvote(advice) {
advice.votes = advice.votes + 1;
return this.httpService.updateData(advice)
.subscribe((res:Response) => {
console.log('in subscribe', res);
});
}
And in my service :
updateData (data:any): Observable<any> {
let datas = JSON.stringify(data);
const headers = { 'Authorization': 'secret' };
return this.http.put(this.url + 'data.json', datas, headers)
.catch((e) => {
console.log(e);
})
.finally(() => {
console.log('finally');
})
}
When I check the response in subscribe method inside the controller, I can see the updated value, but my database is now destroyed.
Before :
After :
As you can see, there no more real object after, it replaces everything.
I think I have to change the url or check the post id, but I don't see how to do.
I didn't find anything in the firebase documentation.. So if someone has an idea..
EDIT AFTER #Luke answer
I updated my code like this :
In my ctrl :
upvote(advice) {
advice.votes = advice.votes + 1;
return this.httpService.updateData(advice)
.subscribe((res:Response) => {
console.log(res);
return res;
})
}
And in the service :
getId() {
this.db.list('data').snapshotChanges().map(actions => {
return actions.map(action => ({ key: action.key, ...action.payload.val() }));
}).subscribe(items => {
return items.map(item => item.key);
});
}
updateData (data:any): Observable<any> {
let updateUrl = this.url + '-p1FFxUqY6u1_AZ3ER4eVUt';
let datas = JSON.stringify(data);
const headers = { 'Authorization': 'secret' };
return this.http.put(updateUrl + 'data.json', datas, headers)
.catch((e) => {
console.log(e);
})
.finally(() => {
console.log('finally');
})
}
I can see the vote counter update in the logs and on the front, but not in the database. When I refresh the page the vote come back to 0.
I think I just forgot something..

If you want to add a new item to a location, you should use POST instead of PUT:
this.http.post(this.url + 'data.json', datas, headers)...
If you want to update an existing item by only providing partial data , you should use PATCH instead of PUT. If your HTTP client doesn't support sending PATCH, you can use a GET and specify PATCH in the X-HTTP-Method-Override header.
For full details on all of these, read the Firebase documentation in saving data using the REST API.

To update your data, you need to know the key of that particular item to put in your url; for example: your-firebase-url/.../L3-bvgdsggdgde. Something like this
updateData (data:any): Observable<any> {
updateUrl = this.url + 'L3-bvgdsggdgde';
let datas = JSON.stringify(data);
const headers = { 'Authorization': 'secret' };
return this.http.put(updateUrl + 'data.json', datas, headers)
.catch((e) => {
console.log(e);
})
.finally(() => {
console.log('finally');
})
}
So, how to take the key from Firebase and reuse it? following this Firebase doc when you get data from Firebase
constructor(afDb: AngularFireDatabase) {
afDb.list('items').snapshotChanges().map(actions => {
return actions.map(action => ({ key: action.key, ...action.payload.val() }));
}).subscribe(items => {
return items.map(item => item.key);
});
}
Your object will have a key property, reuse it in your upvote/update method.

Related

sending results from node.js to react

So on my listPage, I have 2 documents, where I want to be able to click the edit button, and it takes me to the editPage. It does do that right now. but what I have it doing, is making the request through an axios.post, so that it sends the id of the document to the backend, and then sends the results to the front end, where it'll only display the one document according to it's id. here's what I have:
listPage:
const editById = (id) => {
console.log(id);
axios
.post(`/getDocToEdit`, { id: id })
.then(() => {
console.log(id, " worked");
window.location = "/admin/services/:site";
})
.catch((error) => {
// Handle the errors here
console.log(error);
});
};
then it hits this backend route:
app.post('/getDocToEdit', (req, res) => {
var id = req.body.id;
ServicesModel.findOne({_id: id}, function(err,result) {
console.log(result);
res.status(200).send(result)
});
})
then I am just trying to display the document on screen in my editPage, but it doesn't load the result that I am sending through res.status(200).send(result). I have just a table that is supposed to show the record. am I supposed to be doing a call from the front end again or something?
you should save post result in your frontend:
const editById = (id) => {
console.log(id);
axios
.post(`/getDocToEdit`, { id: id })
.then((RESPONSE) => {
console.log(RESPONSE); // do it and if you have the response, everything
is fine and you can use it as the returned data
console.log(id, " worked");
window.location = "/admin/services/:site";
})
.catch((error) => {
// Handle the errors here
console.log(error);
});

Vue JS/Vuex - Call to edit user not saving

I'm trying to make an api call that allows me to edit a single user. The issue that I'm experiencing is that despite the call being successful (and no errors appearing), the changes are not saving. Can someone kindly guide me as to what I'm doing wrong exactly, please? I feel that I'm missing a function that allows me to save the changes after I make the call, but I'm not entirely sure how to go about this.
Edit user details:
setup() {
const store = vuexStore;
const adminId = router.currentRoute.params.adminId;
/** Edit **/
function editUser(formData) {
formData.adminId = adminId;
editAdminAccount(formData).then(response => {
if (response) {
redirectUserTo(ROUTE_NAMES_ADMIN.ADMIN_ACCOUNTS);
saveUserChanges(formData);
}
})
}
// Action
function editAdminAccount(data) {
return store.dispatch(UPDATE_ADMIN_ACCOUNT, data);
}
getSelectedAdmin(adminId);
const selectedAdmin = computed(() => store.getters.getSelectedAdmin);
function getSelectedAdmin(adminId) {
return store.dispatch(GET_ADMIN_BY_ID, adminId)
}
return {
editUser,
selectedAdmin,
}
}
Actions:
updateAdminAccount({commit}, payload) {
let formData = new FormData()
formData.append('email', payload.email)
formData.append('name', payload.name)
formData.append('password', payload.password);
return apiHandler.put(`user/admin/${payload.adminId}`, formData, apiHandler.getAuthHeader()).then(response => {
return !!apiHandler.isSuccess(response.status);
}).catch(error => {
commit(SET_API_ERROR, error);
});
},
You should maybe check what the api call is returning with some console.logs to be sure of the data that is sent back.
Nevertheless, do not have to work with formdata, you can send your query items directly :
updateAdminAccount({commit}, payload) {
return apiHandler.put(`user/admin/${payload.adminId}`, payload, apiHandler.getAuthHeader())
.then(response => !!apiHandler.isSuccess(response.status))
.catch(error => commit(SET_API_ERROR, error));
}
You also should edit the user directly after the api call in the action, and not from the template. So that the logic is kept at one place :
updateAdminAccount({commit}, payload) {
return apiHandler.put(`user/admin/${payload.adminId}`, payload, apiHandler.getAuthHeader())
.then(response => {
if (!!apiHandler.isSuccess(response.status)) {
commit('UPDATE_ADMIN', payload) // payload or response.data depending if api is returning edited object
}
return !!apiHandler.isSuccess(response.status)
})
.catch(error => commit(SET_API_ERROR, error));
}

Can not read http request properly

I'm trying to update the data with using by axios, and I want to use "id" in request url
like http://localhost/api/firstmemory/1
but return 500 Internal Server Error, because my id does not read prpoerly.
my code
const id = detail.id;
const updateFirstInfo = (e) => {
const upInfo = {
first: first,
date: change,
memo: memo,
}
console.log(id); //1
axios
.put(`api/firstmemory/${id}}`, upInfo)
.then(res => {
console.log("ok");
})
.catch(err => {
alert("err");
});
};
How can I fix it?
%7D is the HTML encoding for character }. If you look carefully you have an extra } where you were using template strings. Remove the extra }:
axios
.put(`api/firstmemory/${id}`, upInfo)
.then(res => {
console.log("ok");
})
.catch(err => {
alert("err");
});
Hopefully that helps!

node.js actions on google save conversation data

I have an issue where I can return data from an AXIOS request but I cannot save that data to the conversation user storage (conv.user.storage.caseNumber) using Actions on Google Node.js library. I've tried many different approaches but none are working. I can save data from the intent fine (ex. conv.user.storage.subject and conv.user.storage.description). I've verified via console.log() that the data (i.e. caseNumber) is being returned properly in the response. Any help would be greatly appreciated.
Here is the code:
// Index
const SalesForceProxy = require('./classes/SalesForceProxy');
let proxy = new SalesForceProxy();
app.intent('getDescription - yes - CreateConfirmation', proxy.createCase);
// Proxy.js
module.exports = function () {
this.createCase = function (conv) {
return new Promise(function( resolve, reject) {
axios.post('https://mysite.my.salesforce.com/services/oauth2/token',querystring.stringify(params)).then(function(response){
var caseData = {
"account" : conv.user.storage.accountId,
"recordType" : conv.user.storage.recordTypeId,
"priority" : conv.user.storage.priority,
"subject" : conv.user.storage.subject,
"description" : conv.user.storage.description
};
axios.post('https://mysite.my.salesforce.com/services/apexrest/voicetocase/create',caseData,
{
headers:
{
'Authorization': "Bearer " + response.data.access_token,
'Content-Type': 'application/json'
}
}
)
.then(function(response){
conv.user.storage.caseNumber = response.data.caseNumber;
}.bind({conv: conv}))
.catch((error) => {
console.log(error);
});
resolve()
}.bind({conv: conv})).catch((error) => {
console.log(error);
reject(err);
});
});
}
}
It looks like you're resolving the promise too soon, before you get to set the user storage, which is a second promise.
axiom.post(...)
.then() {
conv.user.storage.X = "";
resolve();
}
This should work as expected.

How do I pass a react DOM state's information to backend(NodeJS) when a button is invoked?

I'm using his logic on the frontend, but I'm having some trouble actually receiving that data on the backend. I'm using the Sails.js framework. Any suggestions?
handleSubmit = () => {
// Gathering together the data you want to send to API
const payload = {
subject: this.state.subject,
message: this.state.message,
};
this.handleAjaxRequest(payload);
};
// Method to send data to the backend
// Making the req -I'm using Axios here.
handleAjaxRequest = (payload) => {
let request = axios({
method: 'post',
url: '/api/',
data: payload,
headers: 'Content-Type: application/json'
});
// Do stuff with the response from your backend.
request.then(response => {
console.debug(response.data);
})
.catch(error => {
console.error(error);
})
};
I used to do this using Express and didn't have these problems.
Any help, method, a suggestion is more than welcome :)
Please forgive my ignorance, I'm just here to learn.
Okay, so the first thing I had to do is generate a new restful API using the command sails generate api data. In the package.json file I set up a proxy that includes the backends endpoint, like this "proxy": "http://localhost:1337" - I mean, you don't need to do this, but if you don't then you have to include this URL part on every request. Because it doesn't change, it's pretty convenient to do so.
On the frontend, I made a function sendData() that takes the necessary data from my previous component (depending on what the user selected) and send that data using axios to the backend -->
sendData = () => {
const { relYear } = this.props.history.location.state.dev;
const { relMonth } = this.props.history.location.state.dev;
const selectedMonth = moment().month(relMonth).format("MM");
const finalSelect = parseInt(relYear + selectedMonth, 10);
axios.post('/data', { 'selectedDate' : finalSelect })
.then(res => console.log('Data send'))
.catch(err => console.error(err));
}
On the backend I fetched the data, did the calculations and send back the result to the frontend of my app. -->
getApiData = () => {
let apiData = [];
axios.get('/data')
.then(res => {
let first = Object.values(res.data.pop()).shift(); // Getting the relevant 'selectedDate'
apiData.push(first);
}).catch(err => console.error(err));
return apiData;
}

Categories