Within a Vue component, I am calling a function from a separate JS file. I then need to call a method in my component just after this first function is completed:
My .vue component:
import myFunction from '#/components/functions';
export default {
name: 'test',
components: {
myFunction,
},
created(){
if (....) {
myFunction.function1(myParam)
.then((response) => {
this.method2();
});
},
methods:{
method2(){
something;
},
}
};
My separate functions.js file:
export default {
function1(myParam) {
...
return true;
},
};
I tried several things such as the last one shown in my code which gives me a
.function1(...).then is not a function
I am sure it is not that complicated but can not find the correct syntax.
The function in your other file could return a Promise or it can except a callback from your view component. Also, if you set this equal to self/vm and then use vm.method2(), this is because in the then callback this is defined in scope of that function not the Vue component.
Related
I have function inside user.js with default export like this
export default {
var getListFriends = async (accessToken) =>{
}
....other function
return {
getListFriends,
...other function...
}
}
then I import it to index.js
import userService from './user';
Then I will add only index.js to plugin.
I can call this.$userService (it shows as anonymous function) but this.$userService.getListFriends return undefined.
How can I call function getListFriends from import.
Thank you very much.
where is user.js?
if its inside plugins directory, you have to use inject to add it to your nuxt.
then you can access it via nuxt object inside your code.
see this example from nuxt docs:
export default ({ app }, inject) => {
// Inject $hello(msg) in Vue, context and store.
inject('hello', msg => console.log(`Hello ${msg}!`))
}
you can see the full document here
ok now for this to work the way you want you need to change your user.js file,
export default {
friends: () => {
console.log('hi bro');
},
notFriends: () => {
console.log('go away man im not your bro');
}
};
something like this.
you dont need inject or app in your user.js.
and your code problem is that you are defining a function and trying to access it's inner values from the outside like:
function boo() {
var b = 0;
}
you can not access the value of b with boo.b. its a local variable to the boo function
instead create a object and have multiple functions inside your object
since yesterday I'm struggling with creating a Vue mixin with a parameter and I'm getting a [Vue warn]: Failed to mount component: template or render function not defined.
Here is my JS file including mixin:
export default (dataObject) => ({
data() {
return {
inputValue: ''
}
},
methods: {
updateValue(newValue) {
this.inputValue = newValue
}
},
mounted() {
this.$bus.$on('value-changed', this.updateValue)
},
beforeDestroy() {
this.$bus.$off('value-changed');
},
computed: {
filteredData() {
if (this.inputValue !== '') {
let newData = Object.keys(dataObject)
.filter(key => key.includes(this.inputValue))
.reduce(
(newData, current) => ((newData[current] = dataObject[current]), newData), {}
)
return newData
}
else return dataObject
}
}
})
And here is my Vue component:
import searchLogic from '../logic/searchLogic.js'
import { mapState } from 'vuex'
export default {
computed: {
...mapState(['champions']),
},
mixins: [searchLogic(this.champions)]
}
Importing this file works, because when I try to import a normal mixin without arguments it works properly. I also tried passing champions and "champions" instead of this.champions but none seem to work. Is it some problem with a mixin? I read that it's possible to return a function returning an object to use parameters when creating mixins.
Based on this article you should be able to statically pass a parameter, but not dynamically.
https://forum.vuejs.org/t/pass-parameters-to-a-mixin-method/26401/3
However, what I can see from the warn you get and the code you shared, is that you haven't defined any template for the component using the template property or the template element in the .vue file.
I want to dynamically set the title of the window for each route, so in each routes: [] child object I have a meta: { title: ... } object. For example:
routes: [
{
path: 'profile/:id',
name: 'Profile',
component: Profile,
meta: {
title: function (to, cb) {
const profileId = parseInt(to.params.id);
// ... do stuff ...
}
}
}
]
I call this title function in an afterEach hook:
router.afterEach((to) => {
document.title = 'My Site';
if (to.meta && to.meta.title) {
to.meta.title(router.app, to, (result) => { document.title += ' | ' + result; });
}
});
In the ... do stuff ... portion I want to call a method from my mixin GetAndStore.js called loadProfile(profileId). I added GetAndStore into the router's mixins, but loadProfile is not available (this.loadProfile is undefined). I loaded GetAndStore globally and tried again with the same results. I've tried every configuration I can think of for the past hour I've not found any way at all to access the methods from GetAndStore from within this setup.
Any ideas of what I'm missing or what I'd need to restructure in order to access mixin methods from within routes->element->meta->title ?
The issue is that...
Mixins are a flexible way to distribute reusable functionalities for Vue components
Vue-router is not a component, nor do you have access to the component loaded for the route.
What I would suggest is making loadProfile a named export from your GetAndStore mixin. Assuming your mixin is exported like
import axios from 'axios' // just an example
export default {
methods: {
loadProfile (profileId) {
return axios.get(...)
}
}
}
you can move your function out of the default export and name it...
export function loadProfile (profileId) {
return axios.get(...)
}
export default {
methods: {
loadProfile
}
}
then you can import just the loadProfile function in your route definitions...
import { loadProfile } from 'GetAndStore'
Of course, you could also import your mixin as it is and just use
import GetAndStore from 'GetAndStore'
// snip
GetAndStore.methods.loadProfile(to.params.id).then(...)
Maybe you can try do it on beforeRouteEnter inside Profile component. So there you can grab meta title and set title of page and there you will have access to mixin methods:
beforeRouteEnter (to, from, next) {
if (to.meta && to.meta.title) {
to.meta.title(router.app, to, (result) => { document.title += ' | ' + result; });
}
},
Docs: https://router.vuejs.org/guide/advanced/navigation-guards.html#in-component-guards
I'm trying to pass the store module namespace via props to a component. When I try and map to getters with the prop, it throws this error,
Uncaught TypeError: Cannot convert undefined or null to object
If I pass the name as a string it works.
This Works
<script>
export default {
props: ['store'],
computed: {
...mapGetters('someString', [
'filters'
])
}
}
</script>
This does not work
this.store is defined
this.store typeof is a String
<script>
export default {
props: ['store'],
computed: {
...mapGetters(this.store, [
'filters'
])
}
}
</script>
I used this style utilising beforeCreate to access the variables you want, I used the props passed into the component instance:
import { createNamespacedHelpers } from "vuex";
import module from '#/store/modules/mymod';
export default {
name: "someComponent",
props: ['namespace'],
beforeCreate() {
let namespace = this.$options.propsData.namespace;
const { mapActions, mapState } = createNamespacedHelpers(namespace);
// register your module first
this.$store.registerModule(namespace, module);
// now that createNamespacedHelpers can use props we can now use neater mapping
this.$options.computed = {
...mapState({
name: state => state.name,
description: state => state.description
}),
// because we use spread operator above we can still add component specifics
aFunctionComputed(){ return this.name + "functions";},
anArrowComputed: () => `${this.name}arrows`,
};
// set up your method bindings via the $options variable
this.$options.methods = {
...mapActions(["initialiseModuleData"])
};
},
created() {
// call your actions passing your payloads in the first param if you need
this.initialiseModuleData({ id: 123, name: "Tom" });
}
}
I personally use a helper function in the module I'm importing to get a namespace, so if I hadmy module storing projects and passed a projectId of 123 to my component/page using router and/or props it would look like this:
import { createNamespacedHelpers } from "vuex";
import projectModule from '#/store/project.module';
export default{
props['projectId'], // eg. 123
...
beforeCreate() {
// dynamic namespace built using whatever module you want:
let namespace = projectModule.buildNamespace(this.$options.propsData.projectId); // 'project:123'
// ... everything else as above with no need to drop namespaces everywhere
this.$options.computed = {
...mapState({
name: state => state.name,
description: state => state.description
})
}
}
}
Hope you find this useful.
I tackled this problem for hours, too. Then I finally came up with one idea.
Add attachStore function in a child vue component. A function nama is not important. Any name is ok except vue reserved word.
export default {
:
attachStore (namespace) {
Object.assign(this.computed, mapGetters(namespace, ['filters']))
}
}
When this vue component is imported, call attachStore with namespace parameter. Then use it at parent components attributes.
import Child from './path/to/child'
Child.attachStore('someStoresName')
export default {
name: 'parent',
components: { Child }
:
}
The error you're encountering is being thrown during Vue/Vuex's initialization process, this.store cannot be converted because it doesn't exist yet. I haven't had to work with namespacing yet, and this is untested so I don't know if it will work, but you may be able to solve this problem by having an intermediary like this:
<script>
export default {
props: ['store'],
data {
namespace: (this.store !== undefined) ? this.store : 'null',
},
computed: {
...mapGetters(this.namespace, [
'filters'
])
}
}
</script>
That ternary expression will return a string if this.store is undefined, if it isn't undefined then it will return the value in this.store.
Note that there is also a discussion about this on Vue's Github page here: https://github.com/vuejs/vuex/issues/863
Until Vue formally supports it, I replaced something like
...mapState({
foo: state => state.foo
})
with
foo () {
return this.$store.state[this.namespace + '/foo'] || 0
}
Where namespace is passed to my child component using a prop:
props: {
namespace: { type: String, required: true }
}
Let say i created a basic modules with simple functions like helper.js
export function HelloChandu() {
//How to access navigator props from here.
}
export function HelloTester() {
HelloChandu();
}
Then I imported this module in my component as import * as Helper from './helper';
In some element I then called onpress={Helper.HelloTester.bind(this)} So by this now I can access this.props in HelloTester function but I can not access this.props in HelloChandu function.
Question : How can I access this.props from any function in my helper.js module ? Like if there are 10-20 functions , and i don't have to pass as parameters around.
Thank You
I am afraid that if you want to access this.props in one of your functions you will need to pass this explicitily or to bind all the functions to the current this before using them.
There are several ways to do so.
function HelloChandu() {
alert(this.props);
}
function HelloTester() {
HelloChandu.apply(this);
// HelloChandu.call(this);
// HelloChandu.bind(this)();
// this::HelloChandu(); // Experimental!
}
const obj = {
props: 'my props'
}
HelloTester.bind(obj)()
An alternative way would be to wrap all the functions in another function.
function helpers() {
const functions = {
HelloChandu: () => {
alert(this.props);
},
HelloTester: () => {
functions.HelloChandu();
}
};
return functions;
}
const obj = {
props: 'my props'
}
helpers.call(obj).HelloTester();
1.You can persist props to AsyncStorage, whenever you need, you can access this props.
2.Or if you are familiar with closure, you can do like this :
function Helper(ps) {
function test() {
console.log(ps.sex);
}
function test2() {
console.log(ps.name);
}
return {
test: test,
test2: test2,
}
}
var obj = Helper({name: 'abc', sex: 'male'});
obj.test();
obj.test2();
then you should export Helper, and import Helper from 'Helper.js'
export function HelloChandu(_this) {
//How to access navigator props from here.
}
export function HelloTester(_this) {
HelloChandu(_this);
}