Stimulus event.params or destructs aren't returning the passed value - stimulusjs

According to the documentation, we would pass a value to a method as parameters in the following way:
<div data-controller="item spinner">
<button data-action="item#upvote spinner#start"
data-item-id-param="12345"
data-item-url-param="/votes"
data-item-payload-param='{"value":"1234567"}'
data-item-active-param="true">…</button>
</div>
And in the controller javascript file, we have a few options. To call event.params, or to destruct.
// ItemController
upvote(event) {
// { id: 12345, url: "/votes", active: true, payload: { value: 1234567 } }
console.log(event.params)
}
upvote({ params: { id, url } }) {
console.log(id) // 12345
console.log(url) // "/votes"
}
Now, here's my own code:
.position-relative.w-100{data: {controller: "content-block"}}
%button.btn.btn-outline-dark{type: "button",
data: {action: "click->content-block#setblock",
setblock_style_param: "H2",
content_block_target: "toolbarH2"}} H2
and in the Controller:
Method 1:
setblock(event) {
alert(event.params)
}
returns [object Object]
Method 2:
setblock({params: { style }}) {
alert(style)
}
returns undefined.
What am I doing wrong?

Related

Ant Design Vue | Upload in Form | How to set initialValue

I'm having problems defining the initialValue in an Upload component, other thing I tried was using a watcher and updating the formValue and the method that update the props FileList. ¿Someone has any idea how this work?
Parent.vue
<Child :file="file"/>
...
async loadFile(item) {
this.loading = true
const { data } = await axios(..., {
...
responseType: 'blob',
})
const file = new File([data], item.name, { type: data.type });
this.file= {
Id: item.id,
Type: item.attributes.type,
IsPublic: item.attributes.is_public,
Descr: item.attributes.descr,
File: [file]
}
this.showForm();
this.loading = false
},
Children.vue
<a-upload
:accept="formats"
:before-upload="beforeUploadEvt"
:disabled="!formats"
:remove="removeFileEvt"
v-decorator="[
'File',
{
valuePropName: 'fileList',
getValueFromEvent: getValueEvt,
rules: [{ required: true, message: 'Select a file' }]
},
]" >
<a-button> <a-icon type="upload" /> Select a file</a-button>
</a-upload>
methods: {
beforeUploadEvt(file) {
this.form.setFieldsValue({
File: [file]
});
return false;
},
removeFileEvt() {
this.formulario.setFieldsValue({
Archivo: []
});
},
getValueEvt(e) {
if (Array.isArray(e)) {
return e;
}
if(e && e.fileList.length > 1) {
return e && [e.fileList[1]];
}
return e && e.fileList;
},
},
watch: {
adjunto: {
immediate: true,
deep: true,
handler(obj) {
if(obj.File) {
this.getValueEvt(obj.File);
// this.formulario.setFieldsValue({
// File: obj.File
// });
}
}
}
}
Trying the most basic example I could think, using the property defaultFileList
<a-upload
:accept="formats"
:before-upload="beforeUploadEvt"
:disabled="!format"
:remove="removeFileEvt"
:default-file-list="this.file.File">
<a-button> <a-icon type="upload" /> Select file</a-button>
</a-upload>
And then, this is the console warnings and errors I got, so seems to be something about type.
If anyone still seeking for an answer for this. You don't need to load file, wrapping your data in appropriate object helps. As in this example
fileList: [{
uid: '-1',
name: 'image.png',
status: 'done',
url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
}]
<a-upload
....
:file-list="fileList"
>

$t is undefined inside of component filter

I have filter on my component
filters: {
formatStatus (value) {
let status = {
active: {
text: this.$t('general.successful'),
class: 'secondary--text'
},
processing: {
text: this.$t('general.processing'),
class: 'tertiary--text'
},
waiting: {
text: this.$t('general.pending'),
class: 'tertiary--text'
}
}
return status[value]
}
}
but i got an error
TypeError: Cannot read property '$t' of undefined
but on methods,
$t is working fine.
Rearraing your code like this. it will work
filters: {
formatStatus (value,self) {
let status = {
active: {
text: self.$t('general.successful'),
class: 'secondary--text'
},
processing: {
text: self.$t('general.processing'),
class: 'tertiary--text'
},
waiting: {
text: self.$t('general.pending'),
class: 'tertiary--text'
}
}
return status[value]
}
}
call filter like :
{{yourvalue | formatStatus(this)}}

Vue.js | Filters is not return

I have a problem.
I am posting a category id with http post. status is returning a data that is true. I want to return with the value count variable from the back. But count does not go back. Return in function does not work. the value in the function does not return from the outside.
category-index -> View
<td>{{category.id | count}}</td>
Controller File
/**
* #Access(admin=true)
* #Route(methods="POST")
* #Request({"id": "integer"}, csrf=true)
*/
public function countAction($id){
return ['status' => 'yes'];
}
Vue File
filters: {
count: function(data){
var count = '';
this.$http.post('/admin/api/dpnblog/category/count' , {id:data} , function(success){
count = success.status;
}).catch(function(error){
console.log('error')
})
return count;
}
}
But not working :(
Thank you guys.
Note: Since you're using <td> it implies that you have a whole table of these; you might want to consider getting them all at once to reduce the amount of back-end calls.
Filters are meant for simple in-place string modifications like formatting etc.
Consider using a method to fetch this instead.
template
<td>{{ categoryCount }}</td>
script
data() {
return {
categoryCount: ''
}
},
created() {
this.categoryCount = this.fetchCategoryCount()
},
methods: {
async fetchCategoryCount() {
try {
const response = await this.$http.post('/admin/api/dpnblog/category/count', {id: this.category.id})
return response.status;
} catch(error) {
console.error('error')
}
}
}
view
<td>{{count}}</td>
vue
data() {
return {
count: '',
}
},
mounted() {
// or in any other Controller, and set your id this function
this.countFunc()
},
methods: {
countFunc: function(data) {
this.$http
.post('/admin/api/dpnblog/category/count', { id: data }, function(
success,
) {
// update view
this.count = success.status
})
.catch(function(error) {
console.log('error')
})
},
},

Polymer - databinding within window.addEventListener for 'deviceorientation'

Please refer below polymer 2.0 element.
<link rel="import" href="../../bower_components/polymer/polymer-element.html">
<dom-module id="xxx">
<template>
<style>
:host {
display: block;
};
</style>
<div>sdsds {{alphaValue}}</div>
<div>sdsd [[betaValue]]</div>
<div>sdsd [[gammaValue]]</div>
</template>
<script>
class xxxClass extends Polymer.Element {
static get is() { return 'xxx'; }
static get properties() {
return {
alphaValue:{
type: Number,
value: 0.0
},
betaValue:{
type: Number,
value: 0.0
},
gammaValue:{
type: Number,
value: 0.0
}
};
}
ready(){
super.ready();
}
connectedCallback() {
super.connectedCallback();
window.addEventListener('deviceorientation',this.getSensorData,true);
}
disconnectedCallback() {
super.disconnectedCallback();
window.addEventListener('deviceorientation',this.getSensorData,true);
}
getSensorData() {
this.alphaValue= event.alpha;
this.betaValue = event.beta;
this.gammaValue = event.gamma;
}
}
window.customElements.define(xxxClass .is, xxxClass );
</script>enter code here
</dom-module>
In the above element, i am not able to bind the properties from the event. Please suggest what i am doing wrong in this element.
In the same element i tried binding property with paper-slider , it is working find ( this code is not included in the snippet )
There is maybe multiple issue on your code :
{{alphaValue}} The two way binding is not useful in that case, just use like the other [[alphaValue]]
On the callback function for the listener, you have to bind the context. That will be window.addEventListener('deviceorientation', this.getSensorData.bind(this), true);. If you don't do that during you callback function process, the values this.alphaValue, this.betaValue and this.gammaValue will be null.
On your callback function you missed a parameter for the event. getSensorData(event)
So the code will look like to :
<dom-module id="os-test">
<template>
<div>sdsds {{alphaValue}}</div>
<div>sdsd [[betaValue]]</div>
<div>sdsd [[gammaValue]]</div>
</template>
<script>
class OsTestElement extends Polymer.Element {
static get is() {
return 'os-test';
}
static get properties() {
return {
alphaValue: {
type: Number,
value: 0.0
},
betaValue: {
type: Number,
value: 0.0
},
gammaValue: {
type: Number,
value: 0.0
}
};
}
connectedCallback() {
super.connectedCallback();
if (window.DeviceOrientationEvent) {
console.log("The browser support device orientation..")
window.addEventListener('deviceorientation', this.getSensorData.bind(this), true);
} else {
console.log("The browser doesn't support device orientation..");
}
}
disconnectedCallback() {
super.disconnectedCallback();
window.removeEventListener('deviceorientation', this.getSensorData.bind(this), true);
}
getSensorData(event) {
this.alphaValue = event.alpha;
this.betaValue = event.beta;
this.gammaValue = event.gamma;
}
}
window.customElements.define(OsTestElement.is, OsTestElement);
</script>
</dom-module>

Bind validation results from ajax request to form model in mithril

Hi I would like to bind html inputs with validation response model returned from API like that:
{"userName":[{"memberNames":["UserName"],"errorMessage":"Field User Name is required."}],"acceptTerms":[{"memberNames":["AcceptTerms"],"errorMessage":"Accepting terms is requried"}]}
And my component in mithril
var RegisterPage = {
vm: {
userName: m.prop(),
password: m.prop(),
confirmPassword: m.prop(),
acceptTerms: m.prop(false)
},
controller: function (args) {
this.title = 'Register new user account';
this.vm = RegisterPage.vm;
this.register = function (e) {
e.preventDefault();
apiRequest({ method: "POST", url: "http://localhost:12116/auth/register", data: RegisterPage.vm }).then(RegisterPage.vm.registerResult)
}
},
view: function (ctrl, args) {
return m('form.input-group',
[
m('.input-row', [m('label', 'Email'), m('input[type=email][placeholder=Your email address like myemail#email.com]', { onchange: m.withAttr("value", ctrl.vm.email) })]),
m('.input-row', [m('label', 'Password'), m('input[type=password][placeholder=your password]', { onchange: m.withAttr("value", ctrl.vm.password) })]),
m('.input-row', [m('label', 'Confirm password'), m('input[type=password][placeholder=your password]', { onchange: m.withAttr("value", ctrl.vm.confirmPassword) })]),
m('.input-row', [m('label', 'Accept terms and conditions'), m('input[type=checkbox]', { onchange: m.withAttr("checked", ctrl.vm.acceptTerms) })]),
m('button[type=submit].btn btn-positive btn-block', { onclick: ctrl.register }, 'Register account')
]);
}
}
I am looking for some generic solution. I would like to mark invalid fields with css class and add field validation message.
UPDATE
In my project I use some wrapper around m.request to get more details when 400 is thrown
function apiRequest(args) {
NProgress.start();
if (!args.unwrapError) {
args.unwrapError = function (data, xhr) {
if (xhr.status === 401)
{
layout.badRequestMsg(xhr.statusText);
}
NProgress.done();
return data;
}
}
if (!args.unwrapSuccess) {
args.unwrapSuccess = function (data, xhr) {
NProgress.done();
return data;
}
}
return m.request(args);
}