I have a vuejs script and need to use an elasticsearch api method.
// ./main.js
var Vue = require('vue');
Vue.use(require('vue-resource'));
import ES from './elasticsearch.js';
new Vue({
el: 'body',
methods: {
search: function() {
// should call the es.search...
}
}
});
and the elasticsearch script:
// ./elasticsearch.js
var es = require('elasticsearch');
var client = new es.Client({
host: 'localhost:9200'
,log: 'trace'
});
client.search({
index: 'my_index',
type: 'my_type',
body: {
fields: {},
query: {
match: {
file_content: 'search_text'
}
}
}
}).then(function (resp) {
var hits = resp.hits.hits;
}, function (err) {
console.trace(err.message);
});
So, in the method search in main.js should call the client.search and send the text to be searched in my server (_search_text_).
How do we bind it? Or how do we use the elasticsearch object inside a vuejs method?
Thanks!
your elasticsearch.js file is not configured correctly as a module: import ES from './elasticsearch' won'T do anything because the file does not export anything.
it should probably look more like this:
// ./elasticsearch.js
var es = require('elasticsearch');
var client = new es.Client({
host: 'localhost:9200'
,log: 'trace'
});
function search (myIndex, myType, searchText)
return client.search({
index: myIndex,
type: myType,
body: {
fields: {},
query: {
match: {
file_content: searchText
}
}
}
}).then(function (resp) {
return hits = resp.hits.hits;
}, function (err) {
console.trace(err.message);
});
export { search }
We define a function named search and export it. Note That I also inxluded return statements to actually return the Promise and result from the function.
Then in main.js we can import it by that name, and use it:
// ./main.js
var Vue = require('vue');
Vue.use(require('vue-resource'));
import { search } from './elasticsearch.js';
new Vue({
el: 'body',
methods: {
search: function() {
var result = search('someindex', 'sometype', 'Search text here' ).then(function(res) {
// do something with the result
})
}
}
});
I suppose "resp.hits.hits" in your code is the search result JSON Object Array ,then you can define your vue instance like below:
// ./main.js
var Vue = require('vue');
Vue.use(require('vue-resource'));
import ES from './elasticsearch.js';
new Vue({
el: 'body',
data:{
searchResults:[] //this tell vue it is an array
}
methods: {
search: function() {
var self = this;
// call the search and get response data
client.search(function(resp){
self.searchResults = resp.hits.hits
})
}
}
});
and in your html,you just bind DOM to searchResults,that's all.
Related
I compiled vue-flash-message component from sources and got the following warning:
✘ http://eslint.org/docs/rules/no-param-reassign Assignment to property of function parameter 'Vue'
src\components\vue-flash-message\index.js:173:5
Vue.prototype[options.storage] = FlashBus;
in the following code:
export default {
install(Vue, config = {}) {
const defaults = {
method: 'flash',
storage: '$flashStorage',
createShortcuts: true,
name: 'flash-message',
};
const options = Object.assign(defaults, config);
...
const FlashBus = new Vue({
data() {
return {
storage: {
},
};
},
methods: {
flash(msg, type, opts) {
return new FlashMessage(FlashBus, msg, type, opts);
},
push(id, message) {
Vue.set(this.storage, id, message);
},
destroy(id) {
Vue.delete(this.storage, id);
},
destroyAll() {
Vue.set(this, 'storage', {});
},
},
});
...
Vue.prototype[options.storage] = FlashBus;
...
},
};
is it possible to correct the code and make it compile without warnings?
This is not an issue.
You have an ES Lint rule setup for no-param-reassign. This conflicts with Vue's way of creating plugins, where you are directed to write to the prototype directly. You can see my statement reinforced here
Your only choice is to fork that project, and ignore the line with your linter if it's bugging you that much.
I am using Vue plugins so that user can access a global component once registering the global component and configuring it inside Vue.use. For this I need to pass some data from Vue.use() to Component.vue.
Take a look at the following code:
Vue.use(MyPlugin, { data: true });
the code of MyPlugin is
import Plugin from './plugin';
const IconPlugin = {
install(Vue, options) {
console.log(options); // Here I can see {data: true}
Vue.component('GlobalComponent', Icon);
},
};
Now I need to pass this options variable to the component. So that a user whenever use
<GlobalComponent />
{data: true} should always be there.
Basically, that is a configuration which user is passing and the further component computation will be dependent on this.
You can use Vue.extend to extend components
var Icon = Vue.extend({
data: function() {
return {
foo: 'fooooo',
bar: 'barr'
}
},
template: '<div><button #click="doFooStuff">{{foo}}</button><button #click="doBarStuff">{{bar}}</button></div>',
methods: {
doBarStuff: function() {
console.log(this.foo, this.bar)
},
doFooStuff: function() {
console.log(this.foo)
}
}
})
const IconPlugin = {
install(Vue, options) {
// console.log(options);
// normalize data (select only props you want)
var data = Object.assign({}, options);
var NewIcon = Icon.extend({
data: function() {
return data;
}
})
Vue.component('GlobalComponent', NewIcon);
},
};
Vue.use(IconPlugin, {
foo: 'FOOO'
});
new Vue({
el: '#app',
components: {
Icon
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
<div id="app">
<icon></icon>
<global-component></global-component>
</div>
it sounds like you want to take a look at the component guide. It would seem that you want to merge the data with where you are passing Icon.
I wrote the following code and Vue complains:
[Vue warn]: Property or method "incidents" is not defined on the
instance but referenced during render. Make sure to declare reactive
data properties in the data option.
I don't see why incidents cannot be accessed?
var app = new Vue({
el: '#app',
data: {
responders: [],
incidents: []
},
mounted: function () {
this.getIncidents();
},
methods: {
getIncidents: function() {
console.log('getIncidents');
var app = this;
this.$http.get('/api/v1/incidents').then(function(response) {
// set data
var incidentsReceived = response.data.map(function (incident) {
return incident;
});
Vue.set(app, 'incidents', incidentsReceived);
})
},
getResponders: function() {
console.log('fetchResponders');
var app = this;
this.$http.get('/api/v1/responders').then(function(response) {
// set data on vm
var respondersReceived = response.data.map(function (responder) {
return responder
});
Vue.set(app, 'responders', respondersReceived);
});
}
}
})
EDIT: Didn't read the code very well for the first time. Verify that you have data inside the response and if not don't set it the incidents array.
data is meant for internal component data modeling, while props, which can be assigned externally, are defined using the props key for your component.
In other words, try:
var app = new Vue({
...,
props: {
incidents: {
type: Array,
required: false //change this as you see fit.
}
},
...
});
For full documentation on component properties, please refer to the official guide.
I'm using a v-for loop with data fetched from JSON file. Is there a way to re-render the DOM and whole v-for loop after loading a new JSON file and replacing the old one?
What I'm trying to achieve is load different sets of products on click and update DOM.
Vue.use(VueResource);
var productsList = new Vue({
el: '#vue',
data: function () {
return {
products: []
};
},
ready: function () {
this.$http.get('data/data.json').then(function (response) {
this.products = response.data;
});
},
methods: {
loadProducts: function (url) {
this.$http.get(url).then(function (response) {
this.products = response.data;
});
}
}
});
The code above should be sufficient for updating your DOM automatically. There are 2 errors however and 1 thing you should consider.
Anonymous functions have different scopes in javascript. This means that when you have an anonymous function function(response) then you lose the scope of the vue instance this. In order to deal with such situations you have to either use arrow functions if you have support for them in your project or save this into another variable before entering the anonymous function.
Vue.use(VueResource);
var productsList = new Vue({
el: '#vue',
data: function () {
return {
products: []
};
},
ready: function () {
var self=this;
this.$http.get('data/data.json').then(function (response) {
self.products = response.data;
});
},
methods: {
loadProducts: function (url) {
var self=this;
this.$http.get(url).then(function (response) {
self.products = response.data;
});
}
}
});
Also if you have this exact code, you should've received an error in browser with products being undefined.
Once you update the products data it will automatically change the DOM as par the latest data, as vue data is reactive. One error I see in your code is, you may have wrong this inside the this.$http block. instead of using function() syntax, use arrow function, which does not bind it's own this, arguments, super, or new.target, like following:
Vue.use(VueResource);
var productsList = new Vue({
el: '#vue',
data: function () {
return {
products: []
};
},
ready: function () {
this.$http.get('data/data.json').then((response) => {
this.products = response.data;
});
},
methods: {
loadProducts: function (url) {
this.$http.get(url).then( (response) => {
this.products = response.data;
});
}
}
});
I am making a request to a 3rd api through my backend. The api returns an array of events to my frontend and I am having trouble storing it in the ember DS. The route for my API request is eventful and the route/model I am trying to create an event for is eventful-event. I call:
this.get('store').createRecord('eventful-event', concert)
in my eventful adapter and get that 'store' is undefined. Here is my code for my eventful route:
import Ember from 'ember';
export default Ember.Route.extend({
model () {
return this.get('store');
},
data : {},
ajax: Ember.inject.service(),
actions: {
searchForEvents (data) {
let eventful = this.get('store').createRecord('eventful', data);
return eventful.save();
// .then(() => this.transitionTo('search-results'));
// return this.get('store').findAll('eventful');
// let something = this.get('store').findAll('eventful');
// console.log('something:', something);
// return eventful.save();
}
}
});
and my eventful adapter:
import ApplicationAdapter from 'ga-wdi-boston.event-bookmarker/application/adapter';
import Ember from 'ember';
export default ApplicationAdapter.extend({
ajax: Ember.inject.service(),
createRecord (store, type, record) {
let serialized = this.serialize(record, { includeId: true});
let data = { serialized };
let dataToSend = {'keywords': record.record.keywords, 'location': record.record.location };
return this.get('ajax').request('/eventful', {
method: 'POST',
data: dataToSend,
}).then((events) => {
events['eventful-event'].forEach(function(concert){
this.get('store').createRecord('eventful-event', concert);
});
});
}
});
This forEach is where the error is thrown. I'm new to ember so I apologize if I am overlooking something simple, or if my approach is not correct. Any advice or help would be much appreciated.
Just put a debugger in. 'This' in the adapter is undefined.
I believe context is your problem. Try using store (argument of adapter method) instead of this.get('store') inside local function:
createRecord (store, type, record) {
let serialized = this.serialize(record, { includeId: true});
let data = { serialized };
let dataToSend = {'keywords': record.record.keywords, 'location': record.record.location };
return this.get('ajax').request('/eventful', {
method: 'POST',
data: dataToSend,
}).then((events) => {
events['eventful-event'].forEach(function(concert){
store.createRecord('eventful-event', concert);
});
});
}