Vue.js data changed but view not - vue.js

I defined an object in data as
export default {
data() {
return {
labelPosition: 'right',
isText: false,
isDate: false,
isExam: false,
isFile: false,
isWrite: false,
stepLists: [],
flowId: '',
txtName: '',
form: {
textName: '',
textPosition: '',
}
the html like this :
when I change the form.textName ,I found it doesn't work
this.$set(this.form, 'textName', temp.name) //not work
this.form={textName:'abc'}
this.form = Object.assign({}, this.form)
//not work
this.$set(this.form,'textName', '---------------------') work well.

Related

Iterator (index) in VUE each function

How can I modify this function, so I will have index (iterator) in there?
attach: function (context, settings) {
$(document, context).once('vue__comparison_training').each(() => {
Vue.component('training', {
template: this.template,
props: ['item', 'user_count'],
data() {
return {
details: false,
participants: false,
productId: false,
variant: false,
prices: false,
inComparison: false,
}
},
I tried for example this modification, it doesn't work, but it doesn't give any errors either:
attach: function (context, settings) {
$(document, context).once('vue__comparison_training').each((index) => {
Vue.component('training', {
template: this.template,
props: ['item', 'user_count', 'index'],
data() {
return {
details: false,
participants: false,
productId: false,
variant: false,
prices: false,
inComparison: false,
}
},

watcher not working to change to lowercase

I am trying to change the users input to lowercase. I know this looks wrong but when I try and type this.email or this.name for the watch it obviously does not work. the v-model is this.email/name accordingly.
What do I need to correct on this
data() {
return {
form: this.$inertia.form({
name: '',
email: '',
password: '',
password_confirmation: '',
birthdate: '',
user_latitude: '',
user_longitude: '',
user_city: '',
user_region: '',
user_country: '',
terms: false,
}),
address: "",
user_address: [],
}
},
watch: {
email(newVal) {
this.form.email = this.form.email.toLowerCase()
},
name(newVal) {
this.form.name = this.form.name.toLowerCase()
}
},
You could try to watch the property path :
watch: {
'form.email'(newVal) {
this.form.email = this.form.email.toLowerCase()
},
or a filter .

Data not being passed from Child Data to Parent Props

I have a Request Form Component, and within this request form Component I have a Dropdown Menu Component, which I will link both below. All values in my table are pushed into an object upon hitting the Submit Button. However my dropdown selection is only being picked up by my console.log and not being pushed into the Object.
I'm not so familiar with Vue, so I'm not sure what direction to go in for fixing this. I'll attach the relevant (?) pieces of code below.
Parent Component:
<SelectComponent :selected="this.selected" #change="updateSelectedValue" />
export default {
fullScreen: true,
name: 'CcRequestForm',
mixins: [BaseForm],
name: "App",
components: {
SelectComponent,
},
data() {
return {
selected: "A",
};
},
props: {
modelName: {
default: 'CcRequest',
},
parentId: {
type: Number,
default: null,
},
},
mounted() {
this.formFields.requester.value = this.currentRequesterSlug;
},
destroyed() {
if (!this.modelId) return;
let request = this.currentCcRequest;
request.params = request.params.filter(p => p.id)
},
computed: {
...mapGetters(['ccTypesForRequests', 'currentRequesterSlug', 'currentCcRequest']),
ccTypesCollection() {
return this.ccTypesForRequests.map((x)=>[x.slug, this.t(`cc_types.${x.slug}`)]);
}
},
methods: {
addParam() {
this.addFormFields(['params'], {
slug: '',
name: '',
isRequired: true,
description: '',
typeSlug: '',
selected: ''
});
},
deleteParam(idx){
this.removeFormFields(['params', idx]);
},
restoreParam(idx){
this.restoreFormFields(['params', idx])
},
$newObject() {
return {
slug: '',
name: '',
isAbstract: false,
requester: '',
description: '',
status: 'inactive',
params: [],
selected: ''
};
},
$extraPrams() {
return {
parentId: this.parentId,
};
},
updateSelectedValue: function (newValue) {
this.selected = newValue;
},
},
watch: {
selected: function (val) {
console.log("value changed", val);
},
},
};
Child Component:
<script>
export default {
name: "SelectComponent",
props: {
selected: String,
},
computed: {
mutableItem: {
get: function () {
return this.selected;
},
set: function (newValue) {
this.$emit("change", newValue);
},
},
},
};
You have to define the emit property in the parent component, or else it won't know what to expect. That would look like:
<SelectComponent :selected="this.selected" #update-selected-value="updateSelectedValue" />
Check out this tutorial for more information: https://www.telerik.com/blogs/how-to-emit-data-in-vue-beyond-the-vuejs-documentation
To update selected property inside the object, in this constellation, you need to update object property manually upon receiving an event, inside of updateSelectedValue method. Other way could be creating a computed property, since it's reactive, wrapping "selected" property.
computed: {
selectedValue () {
return this.selected
}
}
And inside of object, use selectedValue instead of selected:
return {
...
selected: selectedValue
}

VueJS - v-for getting undefined value from props nested object

I'm new to VueJS.
My component's template and the props are below
<template>
<div>
<label>WorkHours</label>
<div v-for="(data, day) in value.config.workingHours">
<label>{{day}}</label>
<hour-range-selector
:value="[data.timeFrom, data.timeTo]"
class="rangeText"
:mandatory="true"
:placeholder="placeholder"
:full-range="['00:00', '23:59']"
#input="(val) => workingHoursChanged(val, day)"
/>
</div>
</div>
</template>
<script>
import HourRangeSelector from '..../HoursRangeSelector';
export default {
name: 'WorkingDaysSelector',
components: {HourRangeSelector},
props: {
value: {
config:{
workingHours: {
monday: {
available: false,
timeFrom: '',
timeTo: '',
},
tuesday: {
available: false,
timeFrom: '',
timeTo: '',
},
wednesday: {
available: false,
timeFrom: '',
timeTo: '',
},
thursday: {
available: false,
timeFrom: '',
timeTo: '',
},
friday: {
available: false,
timeFrom: '',
timeTo: '',
},
saturday: {
available: false,
timeFrom: '',
timeTo: '',
},
sunday: {
available: false,
timeFrom: '',
timeTo: '',
}
}
}
},
placeholder: {
type: Array,
default: () => (['From', 'To']),
},
},
data() {
return {
fullRange: ['00:00', '23:59'],
};
},
methods:{
workingHoursChanged(val, day){
//IN PROGRESS
}
};
</script>
<style scoped>
</style>
If I run the code, I'm getting
vue.runtime.esm.js?2b0e:619 [Vue warn]: Error in render: "TypeError: Cannot read property 'workingHours' of undefined"
Am I approaching correctly? Or How do I achieve this?
Props are the data passed from the parent component to the child one, if you want to define local properties you should define them inside the data option like :
export default {
name: 'WorkingDaysSelector',
components: {HourRangeSelector},
props: {
placeholder: {
type: Array,
default: () => (['From', 'To']),
},
},
data() {
return {
value: {
config:{
workingHours: {
monday: {
available: false,
timeFrom: '',
timeTo: '',
},
tuesday: {
available: false,
timeFrom: '',
timeTo: '',
},
wednesday: {
available: false,
timeFrom: '',
timeTo: '',
},
thursday: {
available: false,
timeFrom: '',
timeTo: '',
},
friday: {
available: false,
timeFrom: '',
timeTo: '',
},
saturday: {
available: false,
timeFrom: '',
timeTo: '',
},
sunday: {
available: false,
timeFrom: '',
timeTo: '',
}
}
}
},
fullRange: ['00:00', '23:59'],
};
},
methods:{
workingHoursChanged(val, day){
//IN PROGRESS
}
};
</script>
<style scoped>
</style>

Upload file with Sails JS and Vue JS

I want to upload a file with Parasails. But I have a error :
<- POST /api/v1/admin/create-article (3ms 400)
| no file attached
| No file was attached.
°
I suppose to my syntaxe is not good.
My html code :
<div class="form-group">
<label for="imgFile">Image:</label>
<input class="form-control-file" id="imgFile" type="file" :class="[formErrors.imgFile ? 'is-invalid' : '']" autocomplete="imgFile">
<div class="invalid-feedback" v-if="formErrors.imgFile">S'il vous plaît, entrez une image valide.</div>
</div>
My action 2 :
module.exports = {
files: ['imgFile'],
friendlyName: 'Create article',
description: '',
inputs: {
imgFile: {
description: 'Upstream for an incoming file upload.',
type: 'ref'
},
titre: {
type: 'string',
required: true,
},
description: {
type: 'string',
required: true,
},
contenue: {
type: 'string',
required: true,
},
postDate:{
type: 'string',
required: false,
},
etiquette:{
type: 'number',
required: false,
},
sharingLink:{
type: 'string',
required: false,
}
},
exits: {
success: {
outputDescription: 'The newly created `Thing`.',
outputExample: {}
},
noFileAttached: {
description: 'No file was attached.',
responseType: 'badRequest'
},
tooBig: {
description: 'The file is too big.',
responseType: 'badRequest'
},
},
fn: async function (inputs, exits) {
var util = require('util');
// Upload the image.
var info = await sails.uploadOne(inputs.imgFile, {
maxBytes: 3000000
})
// Note: E_EXCEEDS_UPLOAD_LIMIT is the error code for exceeding
// `maxBytes` for both skipper-disk and skipper-s3.
.intercept('E_EXCEEDS_UPLOAD_LIMIT', 'tooBig')
.intercept((err)=>new Error('The photo upload failed: '+util.inspect(err)));
if(!info) {
throw 'noFileAttached';
}
var unurl = await sails.helpers.convertUrl(inputs.titre);
await Article.create({titre:inputs.titre, description:inputs.description, contenue:inputs.contenue ,postDate:inputs.postDate ,sharingLink:inputs.sharingLink,url:unurl, etiquette:inputs.etiquette}).fetch();
return exits.success();
}
};
My Root :
'POST /api/v1/admin/create-article': { action: 'admin/create-article' },
I have add this package on my project : sails-hook-uploads
I'm new to Sails and I do not understand this error.
Thanks!
How to upload a file using the new controller actions format in sails.js
Thanks you for your answers !
I think it's a front-end problem. When I make a "console.log" on "inputs" in my action:
{ imgFile:
Upstream {
_fatalErrors: [],
isNoop: true,
_files: [],
timeouts: { untilFirstFileTimer: [Object], untilMaxBufferTimer: [Object] },
_readableState:
ReadableState {
objectMode: true,
highWaterMark: 16,
buffer: [Object],
length: 0,
pipes: null,
pipesCount: 0,
flowing: null,
ended: false,
endEmitted: false,
reading: false,
sync: true,
needReadable: false,
emittedReadable: false,
readableListening: false,
resumeScheduled: false,
destroyed: false,
defaultEncoding: 'utf8',
awaitDrain: 0,
readingMore: false,
decoder: null,
encoding: null },
readable: true,
domain: null,
_events: { error: [Function] },
_eventsCount: 1,
_maxListeners: undefined,
fieldName: 'NOOP_imgFile' },
titre: 'inputs inputs inputs inputs',
description: 'inputs inputs inputs',
contenue: 'inputs inputs inputs',
postDate: '2019-12-21T09:13',
etiquette: 1 }
On the Chrome dev tool :
response of the tool
I think is not a websocket request is XMLHttpRequest (type;xhr).
module.exports = {
friendlyName: 'Update profile avatar',
description: '',
inputs: {
},
exits: {
success: {
responseType: 'redirect'
},
failure: {
responseType: 'redirect'
},
unhandleError: {
responseType: 'redirect',
}
},
fn: async function (inputs, exits) {
let req = this.req;
let res = this.res;
req.file('avatar').upload({
saveAs: fileName,
dirname: require('path').resolve(sails.config.appPath,
'assets/uploads')
}, function whenDone(err, uploadedFile) {
// your code here
});
}
};
This is my code in controller when using req.file('file-name').upload() function. No need to define file in inputs because using req