vue-tables-2 event emit not registering for custom filter - vue.js

I'm getting this error: "TypeError: Event.$emit is not a function" whenever the watcher fires.
I can console log the Event object since I imported it in my main.js file.
I use a named prop because I have 3 different client tables on 1 page. I named the table as rmTable
<v-client-table name="rmTable" :data="filteredRMInvData" :columns="rmColumns" :options="rmOptions" v-if="rmInventoryData.length">
In my watcher:
materialType(value) {
Event.$emit('vue-tables.rmTable.filter::materialtype', value)
}
This is my customFilters in my rmOptions variable:
customFilters: [{
name: 'materialtype',
callback(row, query) {
console.log(row)
console.log(query)
return query.code.includes(row.material_group)
}
}],
How can I do this correctly? At least I should be able to see the row and query logs. I checked the guide on the github page and it seems I followed it correctly.

Assuming you have
Vue.use(VueTables.Event);
Then
materialType(value) {
VueTables.Event.$emit('vue-tables.rmTable.filter::materialtype', value)
}
Event is already a browser interface, which I'm guess is the reason it doesn't work.

Related

how to reload value after clicking in vue

I'm trying to reload values when switching tab without reloading the page. I'm getting the value from a method.
mounted() {
this.getOriginalSpace();
},
methods: {
getOriginalSpace() {
retrieveQuotaSummary(this.value.organisation, this.value.dataCenter)
.then((result) => {
this.quotaSummary = result;
});
}
}
after that, I read the needed value out of quotaSummary like this (computed):
previouslyYarnCPU() {
return this.quotaSummary.currentAcceptedYarnRequest
? this.quotaSummary.currentAcceptedYarnRequest.cpu
: 0;
},
Then, when I switch tab, and call an other function in computed mode, I still have the same value which was loaded above. But when I refresh the page, then I get the correct (new value).
Can someone please help me, how I can get the latest values without refreshing the whole page?
It is difficult as I would need to see the rest of your code but in order to get values when they change you need to use a computed function. You can read more here

How to prevent #change event when changing v-model value

I'm building an auto-complete menu in Vue.js backed by Firebase (using vue-fire). The aim is to start typing a user's display name and having match records show up in the list of divs below.
The template looks like this:
<b-form-input id="toUser"
type="text"
v-model="selectedTo"
#change="searcher">
</b-form-input>
<div v-on:click="selectToUser(user)" class="userSearchDropDownResult" v-for="user in searchResult" v-if="showSearcherDropdown">{{ user.name }}</div>
Upon clicking a potential match the intention is to set the value of the field and clear away the list of matches.
Here is the code portion of the component:
computed: {
/* method borrowed from Reddit user imGnarly: https://www.reddit.com/r/vuejs/comments/63w65c/client_side_autocomplete_search_with_vuejs/ */
searcher() {
let self = this;
let holder = [];
let rx = new RegExp(this.selectedTo, 'i');
this.users.forEach(function (val, key) {
if (rx.test(val.name) || rx.test(val.email)) {
let obj = {}
obj = val;
holder.push(obj);
} else {
self.searchResult = 'No matches found';
}
})
this.searchResult = holder;
return this.selectedTo;
},
showSearcherDropdown() {
if(this.searchResult == null) return false;
if(this.selectedTo === '') return false;
return true;
}
},
methods: {
selectToUser: function( user ) {
this.newMessage.to = user['.key'];
this.selectedTo = user.name;
this.searchResult = null;
}
}
Typeahead works well, on each change to the input field the searcher() function is called and populates the searchResult with the correct values. The v-for works and a list of divs is shown.
Upon clicking a div, I call selectToUser( user ). This correctly reports details from the user object to the console.
However, on first click I get an exception in the console and the divs don't clear away (I expect them to disappear because I'm setting searchResults to null).
[Vue warn]: Error in event handler for "change": "TypeError: fns.apply is not a function"
found in
---> <BFormInput>
<BFormGroup>
<BTab>
TypeError: fns.apply is not a function
at VueComponent.invoker (vue.esm.js?efeb:2004)
at VueComponent.Vue.$emit (vue.esm.js?efeb:2515)
at VueComponent.onChange (form-input.js?1465:138)
at boundFn (vue.esm.js?efeb:190)
at invoker (vue.esm.js?efeb:2004)
at HTMLInputElement.fn._withTask.fn._withTask (vue.esm.js?efeb:1802)
If I click the div a second time then there's no error, the input value is set and the divs disappear.
So I suspect that writing a value to this.selectedTo (which is also the v-model object for the element is triggering a #change event. On the second click the value of doesn't actually change because it's already set, so no call to searcher() and no error.
I've noticed this also happens if the element loses focus.
Question: how to prevent an #change event when changing v-model value via a method?
(other info: according to package.json I'm on vue 2.5.2)
On:
<b-form-input id="toUser"
type="text"
v-model="selectedTo"
#change="searcher">
The "searcher" should be a method. A method that will be called whenever that b-component issues a change event.
But looking at your code, it is not a method, but a computed:
computed: {
searcher() {
...
},
showSearcherDropdown() {
...
}
},
methods: {
selectToUser: function( user ) {
...
}
}
So when the change event happens, it tries to call something that is not a method (or, in other words, it tries to call a method that doesn't exist). That's why you get the error.
Now, since what you actually want is to update searcher whenever this.selectedTo changes, to get that, it is actually not needed to have that #change handler. This is due to the code of computed: { searcher() { already depending on this.selectedTo. Whenever this.selectedTo changes, Vue will calculate searcher again.
Solution: simply remove #change="searcher" from b-form. Everything else will work.
#acdcjunior, thanks for your answer.
Of course just removing the reference to searcher() just means no action is taken upon field value change so the field won’t work at all.
Moving the searcher() function into methods: {} instead of computed: {} means that it will be called on an input event and not a change even (another mystery but not one for today). A subtle difference that takes away the typeahead feature I’m aiming at.
However, it did make me remember that the result of computed: {} functions are cached and will be re-computed when any parameters change. In this case I realised that the searcher() function is dependent upon the this.selectedTo variable. So when the selectToUser() function sets this.selectedTo it triggers another call to searcher().
Fixed now. In case anyone has a similar problem in the future, I resolved this by turning to old fashioned semaphore by adding another variable.
var userMadeSelection: false
Now, searcher() begins with a check for this scenario:
computed: {
searcher() {
if(this.userMadeSelection) {
this.userMadeSelection = false;
return this.selectedTo;
}
…
and then in selectToUser():
this.userMadeSelection = true;

V-select bug while selecting elements in Vuejs

I'm building a small application in vuejs 2 where I'm using v-select package for select box, Problem I'm facing is:
I've declared v-select in my component something like this:
<div class="form-group"><label class="col-sm-2 control-label">Company name:</label>
<div class="col-sm-6">
<v-select :options="companyOptions" v-model="company_name" :on-search="getOptions" placeholder="Company name"></v-select>
</div>
</div>
So accordingly I'm having data defined as company_name, and I'm calling an axios event to get the searchable data, while the component is being loaded I'm calling index data of first 50 set for initial selection and if anybody types then I'm calling a function getOptions to get data related to the input, now suppose if somebody selects any data and then removes it again from the selection and again search with key press event the searchable data is not displayed, I can see that my axios call is working fine and I'm able to get the relevant data. but it is not displaying in dropdown as it says:
Error in render function: "TypeError: Cannot read property 'label' of null"
Which is coming from the company_name model which was selected. Following is my code in codepen
In this my axios is not working as it says mixed content:
https://codepen.io/anon/pen/Bdeqam?editors=1011' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'http://connect.stellar-ir.com/api/companies'. This request has been blocked; the content must be served over HTTPS.
So I'm unable to explain properly in this code set. But my code looks same as declared in codepen.
Help me out in this.
The error is because your computed values are undefined and undefined is not a string, so no string methods (toLowerCase()) are available. The response.data.model.data must look like this:
[
{
id: 1234,
name: 'example'
}, {
id: 12345,
name: 'example2'
}
]
if you get an object instead of an array push it to the array: this.serverData.push(response.data.model.data)
Replace your axios call with:
this.serverData = [
{
id: 1234,
name: 'example'
}, {
id: 12345,
name: 'example2'
}
]
to test it.
In your getOptions() method you calling loading(true or false), but your fetchIndexData() method has an asynchronous axios call. Use async/await, a callback function or a promise chain to wait for the data and show the loading indicator correctly.
On every keypress an request is send to the server i would recommend to use a debounce function.
Tipp
Line 42: https://stackoverflow.com/a/42028776/6429774
axios.post('http://connect.stellar-ir.com/api/companies', searchData).then(response => {
if(response.status === 200)
{
this.serverData = response.data.model.data
}
}).catch(error => {
console.log(error)
});

Unable to get Store inside Sencha Controller

I'm using Sencha Touch 2.3. I'm trying to get a Store instance inside a controller in a similar way thats defined in this article http://www.sencha.com/learn/architecting-your-app-in-ext-js-4-part-3/.
I've defined the 'Location' store in the Controller config. I then try to get the store using 2 methods that both fail. First through Ext.getStore and the second through getLocationStore which should be an autogenerated function. Both fail. The first call returns undefined and the second call throws an exception because the function is not available.
Ext.define('MyApp.controller.Location', {
extend: 'Ext.app.Controller',
config: {
refs: {
locationSearchField: '#locationSearchField'
},
control: {
locationSearchField: {
action: 'onSearchAction'
}
},
stores: [ 'Location' ]
},
onSearchAction: function() {
var locationSearchStore = Ext.getStore('Location');
if (locationSearchStore == undefined) {
Ext.Logger.warn('Could not locate locationSearchStore');
locationSearchStore = this.getLocationStore();
if (locationSearchStore == undefined)
Ext.Logger.warn('Could not location locationSearchStore again!');
else
Ext.Logger.info('Success!');
}
else
Ext.Logger.info('Success!');
}
});
You can get your store by: Ext.data.StoreManager.lookup('Location') (if it's called MyApp.store.Location).
To be sure, that you are in the right context in the onSearchAction, try to call console.dir(this); and check that this is the controller object itself
First of all, you want to access store in sencha touch but you have given link of extjs. Second, you need to define your store first and then add it in app.js file. And then you can access your store by Ext.getStore('Location') method. For reference you shold learn this http://miamicoder.com/2012/sencha-touch-2-stores-adding-removing-and-finding-records/

ExtJS4 trigger doLayout on store load

I have a grid with store: cdStore defined. The grid's records are edited using a form which is bound to the grid data. When updating a record, I would like for the refreshed records to show in the grid.
Currently I have
handler : function() {
areaForm.getForm().submit({
params: { action: "update" }
});
cdStore.loadPage(cdStore.currentPage);
areaGrid.doLayout();
}
It seems like this fails sometimes and older data remains displayed in the grid - perhaps doLayout() is called before the page is fully loaded.
Can I trigger a doLayout on loadPage somehow?
// ...
cdStore.load({
callback: function(){areaGrid.doLayout();},
page: cdStore.currentPage
});
Update
I would appreciate a line or two with an explanation if you would be so kind
You said that "doLayout() is called before the page is fully loaded" and you were right. So the doLayout must be called after the data is loaded. The one way to do that is to use load method. You can pass array of options into this method:
store.load({
page: 2,
limit: 50,
// and
callback: function(){ /*do something*/ }
});
The function you pass as callback is called exactly after the data is loaded. So doLayout() put into callback produces correct behaviour.