v-model and passing a parameter to a rest patch api call - rest

Very new to Vue2, so far so good but I hit a little snag and front end is not my forte.
The table(vue-tables-2) displays correctly what's in the database. I am passing an id in a function to determine what particular row to update but I also want to update the value of the checkbox in the database whenever I press it. How can I achieve that? Many thanks.
<v-client-table :data="tableData" :columns="columns" :options="options" >
<input type="checkbox" v-model="props.row.powerOff" #change="powerOff(props.row.id, props.row.powerOff)">
</v-client-table>
export default {
data() {
return {
columns: ['id', 'name', 'location.address', 'status', 'payment', 'powerOff'],
tableData: []
}
},
created() {
HTTP.get('test').then( response => {this.tableData = response.data;})
.catch( error => {});
},
methods: {
powerOff(id, currentPowerOff) {
var testURL = 'test/' + id
HTTP.patch(testURL, {id, currentPowerOff})//
.then( response => {})
.catch( error => {console.log(error); });
}
}
}

It seems that changing from v-click:on to #change fixed my issue. Reading a little bit more about it, click event is run before v-model has updated the value, while #change does it afterwards. Thank you !

Related

Object in Vuetify select

I want to submit to the server the ID of the selected fixtures but I don't know how.
I have to display an object (that I'm passing in props) in a select menu.
In my select menu I have:
v-select
v-model="form.array"
:items="array"
item-text="name"
item-value="id"
label="Select"
outlined
dense
multiple
chips
return-object
></v-select>
and My form is
data() {
return {
form: Object.assign({}, defaultForm),
valid: true,
defaultForm,
dialog: null,
counterOfUnnamed: '',
checkbox: true,
You can filter the fixtures first and then filter the id property from the filtered array
Here is the working code, it works perfectly
var self = this;
self.fixtures.filter(fixture => self.form.selectedFixture.map(x => x.id).includes(fixture.id)).map(fixture => fixture.id)
In your code add this inside your submit function, dont rewrite the existing this.form.selectedFixture, just craete a new variable assign to it and use then
submit() {
var self = this;
const selectedFixture = self.fixtures.filter(fixture => self.form.selectedFixture.map(x => x.id).includes(fixture.id)).map(fixture => fixture.id);
console.log(selectedFixture);
http.post('group/create', {
name: this.form.groupName,
fixtures: selectedFixture
}).then(result => {
this.groups.push(result);
}).catch(error => {
console.log((error));
});
this.resetForm();
},

Form handling and validation with vuex best practice

I have a big form (10+ inputs) which values I want to bind (like v-model) with object I have in vuex store, on submission it needs to send axios request to server (server will handle validation) and respond with error object (this field is required, this value is too short, etc...).
I will provide minimalistic example with just one input field.
Object student is for student itself obviously, and error object will be there to handle errors from server response.
App.vue
<template>
<div>
<input v-model="student.name">
<span>{{error.name}}</span>
</div>
</template>
<script>
import { mapActions } from "vuex";
export default {
name: "App",
computed: {
student.name: {
get () {
return this.$store.state.student.name
},
set (value) {
this.$store.commit('setStudentName', value)
}
},
error.name: {
get () {
return this.$store.state.error.name
},
set (value) {
this.$store.commit('setErrorName', value)
}
}
}
}
</script>
and this is mu vuex store:
export default {
state: {
student: { name: ''},
error: { name: ''}
},
mutations: {
setStudentName: (state, student.name) => (state.student.name = student.name),
setErrorName: (state, error.name) => (state.error.name = error.name)
}
}
So this works perfectly, but imagine having 10+ inputs and having to write setters and getters for 10 inputs x 2 objects (student and error), that is like 40 setters&getters at least.
Is there a easier way to do this?
I have also tried vuex-forms which is great, but package is incomplete and documentation is missing, tried vuex-map-fields, which is good only for handling one object at the time.
All suggestions are welcome, what it the correct way to do this?

Uspert multiple documents with MongoDB/Mongoose

Say I have a list of models:
const documents = [{}, {}, {}];
And I want to insert these into the DB, or update them all, but only if a condition is met:
Model.update({isSubscribed: {$ne: false}}, documents, {upsert:true},(err, result) => {
});
The above signature is surely wrong - what I want to do is insert/update the documents, where the condition is met.
There is this Bulk API:
https://docs.mongodb.com/manual/reference/method/Bulk.find.upsert/
but I can't tell if it will work when inserting multiple documents.
Imagine this scenario: We have a list of employees and a form of some sorts to give them all a penalty, at once, not one by one :)
On the backend side, you would have your eg addBulk function. Something like this:
Penalty controller
module.exports = {
addBulk: (req, res) => {
const body = req.body;
for (const item of body) {
Penalty.create(item).exec((err, response) => {
if (err) {
res.serverError(err);
return;
}
});
res.ok('Penalties added successfully');
}
}
Then you'll probably have an API on your frontend that directs to that route and specific function (endpoint):
penaltyApi
import axios from 'axios';
import {baseApiUrl} from '../config';
const penaltyApi = baseApiUrl + 'penalty'
class PenaltyApi {
static addBulk(penalties) {
return axios({
method: 'post',
url: penaltyApi + '/addBulk',
data: penalties
})
}
}
export default PenaltyApi;
...and now let's make a form and some helper functions. I'll be using React for demonstration, but it's all JS by the end of the day, right :)
// Lets first add penalties to our local state:
addPenalty = (event) => {
event.preventDefault();
let penalty = {
amount: this.state.penaltyForm.amount,
unit: this.state.penaltyForm.unit,
date: new Date(),
description: this.state.penaltyForm.description,
employee: this.state.penaltyForm.employee.value
};
this.setState(prevState => ({
penalties: [...prevState.penalties, penalty]
}));
}
Here we are mapping over our formData and returning the value and passing it to our saveBulkEmployees() function
save = () => {
let penaltiesData = Object.assign([], this.state.penalties);
penaltiesData.map(penal => {
penal.employeeId = penal.employee.id;
delete penal.employee;
return penaltiesData;
});
this.saveBulkEmployees(penaltiesData);
}
...and finally, let's save all of them at once to our database using the Bulk API
saveBulkEmployees = (data) => {
PenaltyApi.addBulk(data).then(response => {
this.success();
console.log(response.config.data)
this.resetFormAndPenaltiesList()
}).catch(error => {
console.log('error while adding multiple penalties', error);
throw(error);
})
}
So, the short answer is YES, you can absolutely do that. The longer answer is above :) I hope this was helpful to you. If any questions, please let me know, I'll try to answer them as soon as I can.

Sending data from React form to Firebase database

I am working on a form in React and wanting to send the data collected to the Firebase database. However, I'm not entirely sure on how to set this up efficiently. I have posted below some snippets of some of the code I have so far.
Here is the beginning of my component. From my understanding the componentDidMount is pulling the data from the json file to have into those fields. But I'm not sure if that is where I should enter the code to send to Firebase.
class FormContainer extends Component {
constructor(props) {
super(props);
this.state = {
firstName: '',
lastName: '',
email: '',
startDate: moment(),
courseName: '',
courseCity: '',
courseStateOptions: [],
courseStateSelection: '',
holeNumberOptions: [],
holeNumberSelection: '',
yardage: '',
clubOptions: [],
clubSelection: ''
};
this.handleFormSubmit = this.handleFormSubmit.bind(this);
this.handleClearForm = this.handleClearForm.bind(this);
this.handleFirstNameChange = this.handleFirstNameChange.bind(this);
this.handleLastNameChange = this.handleLastNameChange.bind(this);
this.handleEmailChange = this.handleEmailChange.bind(this);
this.handleDateChange = this.handleDateChange.bind(this);
this.handleCourseNameChange = this.handleCourseNameChange.bind(this);
this.handleCourseCityChange = this.handleCourseCityChange.bind(this);
this.handleCourseStateSelect = this.handleCourseStateSelect.bind(this);
this.handleHoleNumberSelect = this.handleHoleNumberSelect.bind(this);
this.handleYardageChange = this.handleYardageChange.bind(this);
this.handleClubSelect = this.handleClubSelect.bind(this);
}
componentDidMount() {
fetch('./nhior_db.json')
.then(res => res.json())
.then(data => {
this.setState({
firstName: data.firstName,
lastName: data.lastName,
email: data.email,
date: data.date,
courseName: data.courseName,
courseCity: data.courseCity,
courseStateOptions: data.courseStateOptions,
courseStateSelection: data.courseStateSelection,
holeNumberOptions: data.holeNumberOptions,
holeNumberSelection: data.holeNumberSelection,
yardage: data.yardage,
clubOptions: data.clubOptions,
clubSelection: data.clubSelection
});
});
}
Below this I have all of my handleFirstNameChange() functions, etc.. I won't post them all in here, but here are a few for reference.
handleCourseNameChange(e) {
this.setState({ courseName: e.target.value }, () => console.log('course name:', this.state.courseName));
}
handleCourseCityChange(e) {
this.setState({ courseCity: e.target.value }, () => console.log('course city:', this.state.courseCity));
}
handleCourseStateSelect(e) {
this.setState({ courseStateSelection: e.target.value}, () => console.log('course state', this.state.courseStateSelection));
}
handleHoleNumberSelect(e) {
this.setState({ holeNumberSelection: e.target.value}, () => console.log('hole number', this.state.holeNumberSelection));
Then I have my handleClearForm() and handleFormSubmit()
handleFormSubmit(e) {
e.preventDefault();
const formPayload = {
firstName: this.state.firstName,
lastName: this.state.lastName,
email: this.state.email,
date: this.state.date,
courseName: this.state.courseName,
courseCity: this.state.courseCity,
courseStateSelection: this.state.courseStateSelection,
holeNumberSelection: this.state.holeNumberSelection,
yardage: this.state.yardage,
clubSelection: this.state.clubSelection
};
alert('Thanks for the submission!');
// console.log('Send this in a POST request:', formPayload)
this.handleClearForm(e);
}
Lastly the render method contains all the inputs, here are a few.
render() {
return (
<form className="container" onSubmit={this.handleFormSubmit}>
<h6>If you are one of the SPECIAL FEW to make a hole in one, you have the opportunity to record your success in the national registry!
Please enter your information, the date of your Hole-In One and click Continue.</h6>
<SingleInput
inputType={'text'}
title={'First name'}
name={'name'}
controlFunc={this.handleFirstNameChange}
content={this.state.firstName}
placeholder={'First Name'} />
<SingleInput
inputType={'text'}
title={'Last name'}
name={'name'}
controlFunc={this.handleLastNameChange}
content={this.state.lastName}
placeholder={'Last Name'} />
<SingleInput
inputType={'text'}
title={'Email'}
name={'name'}
controlFunc={this.handleEmailChange}
content={this.state.email}
placeholder={'Email'} />
<DatePicker
selected={this.state.startDate}
onChange={this.handleDateChange}/>
I just need to know if there is a better more efficient way to send the data collected to Firebase.
If I understand correctly, you are asking two questions:
where I should enter the code to send to Firebase, and
how to set this up efficiently.
The answer depends on what you mean by "efficient".
To simply get your example to work, you add the firebase call inside handleFormSubmit, right where your console.log is. But you probably knew that.
So what's efficient? If you want to organize your code in a manageable way, then a good start is a state framework like MobX or Redux. It is a good idea to keep most of your state (i.e. data you get from firebase) in one place.
I use react-redux, and essentially separate my logic into 2 kinds of controllers. One controller (often called async functions or thunks) handles your database fetching/saving and the other controller prepares (maps) your data and event handlers for the view. This way I rarely use this.setState(...) or this.state and get a clear, unit-testable separation of concerns.
With your example, you would dispatch an async action (in redux terminology) in handleFormSubmit, and have this action push data to firebase and reflect the change (e.g. saving status) in the global state store. Then you simply render your component with data passed from the store into the props.

Ionic 2 MEAN Application doesn't return updated data on get request

I've been having this weird issue with an application I'm building. Essentially a function is invoked I want to read in a user's current game statistics -Wins, losses, draws etc - I do this using a service which creates an observable and consumes data from my rest api. On first call of this method the data read in is the most current up to date version but after this point I update the document for the user in the database and then when I execute the function again it reads in the original document before the update. However when I check the database the document has in face been updated.
Here is my provider function for consuming the data.
getUser(id) {
if (this.data) {
return Promise.resolve(this.data);
}
return new Promise(resolve => {
this.http.get('https://pitchlife-hearts.herokuapp.com/api/users/' + id)
.map(res => res.json())
.subscribe(data => {
this.data = data;
resolve(this.data);
});
});
}
Here is the call I make in my function.
play(challenger, opponent) {
this.userService.getUser(_id).then((data) => {
this.challenger_account = {
_id: data._id,
points: data.maroon_points,
wins: data.wins,
draws: data.draws,
losses: data.losses
};
Here is my update call.
this.userService.updateUser(this.challenger_account);
Here is my api endpoint call as well although this does work every time I update the data.
app.post('/api/users/update', function (req, res) {
// Update a user
var options = {};
User.update({_id : req.body._id }, {
maroon_points: req.body.points,
wins: req.body.wins,
draws: req.body.draws,
losses: req.body.losses
}, options,
function (err, user) {
if (err)
res.send(err);
res.json(user);
});
});
Any help with this would be hugely appreciated as this is driving me crazy.
When are you updating the this.data property that the getUser(id) { ... } method uses?
Because the first time the getUser(id) {...} method is executed, this.data is null and because of that the http request is made. But after that, the value of this.data is always returned, but if you don't update it manually, it'll be always the first value it was set to.