Axios.put ReactJS - javascript

It's kinda working,but problem is it copies the file which is being updated and puts it in the end of page,All I'm trying to do display update on the item
Here what I'm trying to do
submitEdit = (id, value) => {
let {todos} = this.state
todos.map((item => {
if (item._id === id) {
axios
.put(`http://localhost:8080/edit/${id}`, {
todo: value,
})
.then((res) => {
this.setState({
todos:[...todos,{todo:value}]
})
console.log("res", res);
})
.catch((err) => {
console.log("err", err);
});
}
}))
}
beside this everything is working fine

You need to update the state by using the index so that the todo element is updated and not copied and added to the end
You can use Array.prototype.slice with spread syntax to do that
todos.map(((item, i) => {
if (item._id === id) {
axios
.put(`http://localhost:8080/edit/${id}`, {
todo: value,
})
.then((res) => {
this.setState({
todos:[...todos.slice(0, i),{todo:value}, ...todos.slice(i + 1)]
})
console.log("res", res);
})
.catch((err) => {
console.log("err", err);
});
}
}))

Related

Trying to make an array of objects, but getting back an array with empty objects

I'm new to javascript and there's a problem I'm not all able to solve.
I have one array of objects, which contains 2 attributes. I want to connect the attributes, one of which will be a key and the other will be a value.
this is what I have:
[{"prefer":"code_html","rating":"5"},{"prefer":"code_css","rating":"3"}]
This is what I want to get:
[
{
"code_html": "5"
},
{
"code_css": "3"
}
]
I run this function:
const array = [{"prefer":"code_html","rating":"5"},{"prefer":"code_css","rating":"3"}]
const result = array.map(({prefer, rating}) => ({[prefer]: rating}));
console.log(result);
But I can not understand why it does not work for me.
This is the print I get, I do not understand what is wrong
[{},{},{}]
I use this code in nodeJs, maybe that's why I have a problem:
exports.addUserKmeansMatchVer2 = (req, res) => {
console.log("addUserKmeansMatch function filter:");
arr = [];
if(req.query.filterArray)
{
arr = [...req.query.filterArray];
console.log("line 256" + typeof(req.query.filterArray));
//this is print line 256object
console.log("line 257" +arr);
//this is works prints: line 257{"prefer":"sport_swimming","rating":"3"},{"prefer":"code_html","rating":"5"},{"prefer":"code_css","rating":"3"}
console.log("line 258" + req.query.filterArray);
//print exactly the same as line 257
}
let onlyPreferencesAllow = [];
arr.forEach(({prefer,rating}) => onlyPreferencesAllow.push({[prefer]: rating}));
console.log("line 262" + JSON.stringify(onlyPreferencesAllow));
//this is NOT work prints: line 262[{},{},{}]
db.doc(`/match/${req.user.handle}`)
.set("testing")
.then(() => {
return res.json({ message: "Details added successfully" });
})
.catch((err) => {
console.error(err);
return res.status(500).json({ error: err.code });
});
}
})
})
};
I noticed that in line 257 it prints for me without the parentheses of the array without [], but in line 262 it prints with the parentheses [], I do not quite understand it
I thought of something I forgot to mention,
I get the req.query.filterArray, through the params.
Here's how I do it:
export const makeMatchVer2 = (data) => (dispatch) => {
dispatch({ type: LOADING_DATA });
axios
.get('/kmeansFilter', {
params: {
filterArray: data
}
})
.then((res) => {
dispatch({
type: MAKE_MATCH,
payload: res.data
});
})
.catch((err) => {
dispatch({
type: MAKE_MATCH,
payload: []
});
});
};
the data itself is an array, maybe here i do the mistake
The solution that worked for me:
When I send an array in params to api, I need to use JSON.stringify.
export const makeMatchVer2 = (data) => (dispatch) => {
dispatch({ type: LOADING_DATA });
axios
.get('/kmeansFilter', {
params: {
filterArray: JSON.stringify(data)
}
})
.then((res) => {
dispatch({
type: MAKE_MATCH,
payload: res.data
});
})
.catch((err) => {
dispatch({
type: MAKE_MATCH,
payload: []
});
});
};
And when I get the answer in nodeJS, I have to use JSON.parse
exports.addUserKmeansMatchVer2 = (req, res) => {
console.log("addUserKmeansMatch function filter:");
arr = [];
if(req.query.filterArray)
{
arr = JSON.parse(req.query.filterArray);
}
let onlyPreferencesAllow = [];
arr.forEach(({prefer,rating}) => onlyPreferencesAllow.push({[prefer]: rating}));
console.log("line 262" + JSON.stringify(onlyPreferencesAllow));
db.doc(`/match/${req.user.handle}`)
.set("testing")
.then(() => {
return res.json({ message: "Details added successfully" });
})
.catch((err) => {
console.error(err);
return res.status(500).json({ error: err.code });
});
}
})
})
};

Unable to fetch user location details by IP

hello im new to react and trying to build a weather site. i have a search functionality which works, but im also trying to get the local weather for the user.
for this i get city from: https://geoip-db.com/json/
weather api: https://api.openweathermap.org/data/2.5/
then i save that city as a variable in the state so i can use it in the api.
here is the code:
`
state = {
geoipCity: "",
}
componentDidMount(){
const geoApiUrl = "https://geoip-db.com/json/";
fetch(geoApiUrl)
.then(res => res.json())
.then(geoip => {
this.setState({ geoipCity: geoip.city })
})
.catch(err => {
console.log("Fetch error: " + err);
});
console.log("prefetch:" + this.state.geoipCity)
const weatherApiUrl = `${api.base}weather?q=${this.state.geoipCity}&weather&units=metric&APPID=${api.key}`;
fetch(weatherApiUrl)
.then(res => res.json())
.then(result => {
console.log(result)
let locationOutput = document.querySelector("#locationOutput");
if(result.cod === "404"){
locationOutput.innerHTML = `${this.state.geoipCity} is not a valid city name`;
}
/*
locationOutput.innerHTML = `
Your live in ${this.state.geoipCity} and it feels like ${result.main.feels_like}°C`;
*/
})
.catch(err => {
console.log("Fetch error: " + err);
});
}
`
so the first fetch gets the city and saves it in the geoipCity state variable. this i try to use it in the api search.
however right before that i have:
console.log("prefetch:" + this.state.geoipCity)
which shows me that this.state.geoipCity is empty.
any ideas?
EDIT: SOLVED, HERE IS THE CODE IN CASE ANYONE BENEFITS FROM IT IN THE FUTURE
`
componentDidMount(){
const geoApiUrl = "https://geoip-db.com/json/";
fetch(geoApiUrl)
.then(res => res.json())
.then(result => {
console.log(result)
this.setState({ geoipCity: result.city }, () => {
//console.log(this.state);
const weatherApiUrl = `${api.base}weather?q=${this.state.geoipCity}&weather&units=metric&APPID=${api.key}`;
fetch(weatherApiUrl)
.then(res => res.json())
.then(result => {
console.log(result)
let locationOutput = document.querySelector("#locationOutput");
if(result.cod === "404"){
locationOutput.innerHTML = `${this.state.geoipCity} is not a valid city name`;
}
locationOutput.innerHTML = `
Your live in ${this.state.geoipCity} and it feels like ${result.main.feels_like}°C`;
})
.catch(err => {
console.log("Fetch error: " + err);
});
});
//this.setState({ geoipCity: geoip.city })
})
.catch(err => {
console.log("Fetch error: " + err);
});
}
`
this.setState is async.
You need to use the callback of setState in order to console.log the new state.
this.setState({ geoipCity: geoip.city }, (newState) => {
console.log(newState);
});
Every setState will re-render the component but componentDidMount only executes on the first render.

Update V-if in vuejs reactively

I was wondering if it's possible to re-render this v-if statement inside my component.
I am enabling/disabling a user account through firebase admin functions. This currently works, however whenever I disable a user I have to refresh the page in order to show updates, I can manually refresh, but wondered if there is a way to do this with reactivity? I've tried to update the array manually (UsersAuth contains all the users from Firebase, with the disabled: true|false boolean).
html
<span v-if="usersAuth[index].disabled === true"> <button type="button" v-on:click="enableUser(user.id, index)" class="btn btn-success">Enable</button></span>
<span v-if="usersAuth[index].disabled === false"><button type="button" v-on:click="disableUser(user.id)" class="btn btn-primary">Disable</button></span>
VueJS Methods
data () {
return {
users: [],
user: null,
usersAuth: null,
selecteduser: null
}
},
created () {
// call all users from the firebase store.
const addMessage = firebase.functions().httpsCallable('listAllUsers')
addMessage()
.then(result => {
this.usersAuth = result.data.users
})
firebase.auth().onAuthStateChanged((user) => {
this.user = user
})
this.users = []
firebase
.firestore()
.collection('roles')
.get()
.then(snap => {
snap.forEach(doc => {
const user = doc.data()
console.log(doc.data())
user.id = doc.id
this.users.push(user)
})
})
// get the users' enabled status
},
disableUser (uid) {
const addMessage = firebase.functions().httpsCallable('disableUser')
const data = { uid: uid }
addMessage(data)
.then((result) => {
if (result === true) {
console.log(this.userAuth)
}
})
.catch(function (error) {
console.log(error)
})
},
enableUser (uid, index) {
const addMessage = firebase.functions().httpsCallable('enableUser')
const data = { uid: uid }
addMessage(data)
.then((result) => {
this.usersAuth[index].disabled = true
})
.catch(function (error) {
console.log(error)
})
},
listAllUsers () {
const addMessage = firebase.functions().httpsCallable('listAllUsers')
addMessage()
.then((result) => {
console.log(result)
})
.catch(function (error) {
console.log(error)
})
}
Firebase function (if you require this)
exports.disableUser = functions.https.onCall(async (data, context) => {
if (!context.auth.token.superadmin) return
try {
listUsers = admin.auth().updateUser(data.uid, {
disabled: true
})
.then(function() {
console.log("Successfully disabled user " + data.uid);
})
return true
} catch (error) {
console.log(error)
}
});
exports.enableUser = functions.https.onCall(async (data, context) => {
if (!context.auth.token.superadmin) return
try {
listUsers = admin.auth().updateUser(data.uid, {
disabled: false
})
.then(function() {
console.log("Successfully disabled user " + data.uid);
})
return true
} catch (error) {
console.log(error)
}
});
exports.listAllUsers = functions.https.onCall((data, context) => {
if (!context.auth.token.superadmin) return
try {
return admin.auth().listUsers()
} catch (error) {
console.log(error)
}
});
In your enableUser method, this.usersAuth[index].disabled = true should be this.usersAuth[index].disabled = false, so that you're enabling the user rather than disabling them.
You can read The Vue Instance and Reactivity in Depth for more information about how reacitivty works with Vue.
When a Vue instance is created, it adds all the properties found in
its data object to Vue’s reactivity system. When the values of those
properties change, the view will “react”, updating to match the new
values.
On a side note, if disabled is either true or false, you can simplify your code to:
<span v-if="usersAuth[index].disabled">
and <span v-else>

Query return as undefined using knex

I need to register a new user, when receiving the parameters make a query using the city name to get the state and city id (both are foreign keys). I implemented a function to find the ids. Inside the function using data.id the id is returned correctly. But at the time of insert in database is being inserted "undefined".
Apparently the save operation is being executed before the findCity and findState functions return the value.
execution flow
cidade = city, estado = city
module.exports = app => {
const obterHash = (senha, callback) => {
bcrypt.genSalt(10, (err, salt) => {
bcrypt.hash(senha, salt, null, (err, hash) => callback(hash))
})
}
var idCidade;
var idEstado
function findCidade(cidade, ) {
app.db('cidades')
.where({ nome: cidade })
.first()
.then(data => {
idCidade = data.id
console.log('inside findCity. data.id: '+data.id)
}).catch((err) => console.log("erro cidade", err));
return
}
function findEstado(uf) {
app.db('estados')
.where({ uf: uf })
.first()
.then(data => {
idEstado = data.id
console.log('inside findState. data.id: '+data.id)
}).catch((err) => console.log("erro estado", err));
}
const save = (req, res) => {
console.log("\n")
findCidade(req.body.cidade)
findEstado(req.body.uf)
obterHash(req.body.senha, hash => {
const senha = hash
console.log("Will be inserted. idCity: "+idCidade+" idState: "+idEstado)
app.db('salao')
.insert({ idcidade: idCidade,
idestado: idEstado,
senha})
.then(_ => res.status(200).send())
.catch(err =>{res.status(400).json(err)})
})
}
return { save }
}
I'm from Brazil and I'm using a translator, sorry for the spelling mistakes.
You are welcome to the asynchronous world!
General explanation: You are going to use results of a database querying before it will happen. Your program have to wait the results (idCidade, idEstado) before you can use it. Because of it you can find the record Will be inserted... first in your logs.
For the explanation I'm going to use Minimal Reproducible Example.
function findCidade(cidade) {
return Promise.resolve(1);
}
function findEstado(uf) {
return Promise.resolve(1);
}
Promise.all([findCidade(), findEstado()])
.then((data) => console.log(data));
The output is:
[ 1, 1 ]
To solve the issue you have to:
Return the promise explicitly with return statement.
Await the results by async/await or Promise interface methods. Or use callbacks if it is more suitable to you.
module.exports = app => {
const obterHash = (senha, callback) => {
bcrypt.genSalt(10, (err, salt) => {
bcrypt.hash(senha, salt, null, (err, hash) => callback(hash))
})
};
function findCidade(cidade, ) {
return app.db('cidades')
.where({ nome: cidade })
.first()
.then(data => {
idCidade = data.id
console.log('inside findCity. data.id: '+data.id)
}).catch((err) => console.log("erro cidade", err));
}
function findEstado(uf) {
return app.db('estados')
.where({ uf: uf })
.first()
.then(data => {
idEstado = data.id
console.log('inside findState. data.id: '+data.id)
}).catch((err) => console.log("erro estado", err));
}
const save = (req, res) => {
console.log("\n");
Promise.all([findCidade(req.body.cidade), findEstado(req.body.uf)])
.then((data) => {
const [idCidade, idEstado] = data;
obterHash(req.body.senha, hash => {
const senha = hash;
console.log("Will be inserted. idCity: "+idCidade+" idState: "+idEstado);
app.db('salao')
.insert({ idcidade: idCidade,
idestado: idEstado,
senha})
.then(_ => res.status(200).send())
.catch(err =>{res.status(400).json(err)})
})
})
.catch((err) => console.log("general error", err));
};
return { save }
}

Mongoose promise in foreach failed in my case

How to do promise with forEach? I want to get all jobs, but get the data of applicants. My Job schema already have the applicant id, but how to query the user and merge their detail in the output?
Job.find({}).then(result => {
result.forEach(obj =>{
const applicant_id = obj.applicant._id
if(applicant_id){
User.findOne({_id: applicant_id})
.then(user=>{
return res.json({
status: 1,
data: {
...obj,
applicant: {
...user
}
}
})
})
}
})
}).catch(err => {
if(err){
return res.status(400).send({
msg: err
})
}
})
I tried Promise but I'm stuck merging user into the Job obj,
Job.find({}).then(result => {
let promiseArray = []
result.forEach(obj =>{
const applicant_id = obj.applicant._id
if(applicant_id){
promiseArray.push(
User.findOne({_id: applicant_id}))
}
})
return Promise.all(promiseArray)
}).then(user => {
console.log(user)
//this work but this is only the user's data,
//I need it to be within obj which is Job data
})
You first need to filter items in result to exclude those without applicant id, then map this array to array of promises, and finally pass it to Promise.all. This should do it:
Job.find({}).then(result => {
const promises = result
.filter(obj => obj.applicant._id)
.map(obj => {
const applicant_id = obj.applicant._id
return User.findOne({ _id: applicant_id })
.then(user => {
return res.json({
status: 1,
data: {
...obj,
applicant: {
...user
}
}
})
})
})
return Promise.all(promises)
}).catch(err => {
if (err) {
return res.status(400).send({
msg: err
})
}
})
Here's a tested and working solution:
Job.find({ applicant: { $ne: null } }).populate('applicant').then(result => {
res.send(result);
}).catch(err => {
return res.status(400).send({
msg: err
})
});

Categories