I am trying to do an axios request but whatever I do I get the same error message.
The message is:
Parsing error: Unexpected token, expected ",". The error points at axios.get (it points at the dot between "axios" and "get" in the error message). It gives the same message if I put something like console.log in the code.
I am basically just using a regular default vue project and the only thing I have done is to add the following code in HelloWorld.vue.
<script type="text/javascript">
import axios from 'axios';
// const axios = require('axios');
export default {
name: 'HelloWorld', // console.log("hi"),
props: {
msg: String //response
},
methods: {
axios.get('https://swapi.co/api/people/1')
.then(function(response){
console.log(response)
})
}
}
</script>
Can someone please tell me why this error keeps coming up, I am guessing this is pretty simple but I am losing my mind at this point. Thank you
You won't be able to access your axios method, since it isn't actually being declared as a function. You can write vue methods in two ways, both equivalent (to my knowledge).
export default {
data() {
item: []
},
methods: {
getStarWarsCharacters() {
// axios call goes here
}
}
}
Other way is like this:
export default {
data() {
item: []
},
methods: {
getStarWarsCharacters: () => {
// axios call goes here
}
}
}
I suspect that if you write it in the first way, Vue is actually converting to the second.
axios must be globalized in your root file.
const axios = require('axios');
global.axios = axios;
Related
I'm currently implementing user authentication on my website, and I'm trying to restrict access to the login and signup pages if the user is logged in. To do so, I am implementing this getServerSideProps to redirect the user if they're logged in:
export async function getServerSideProps(context) {
if (context.req.cookies.user) {
return {
redirect: {
destination: '/',
permanent: true,
},
}
}
return {}
}
If I return an empty object ({}), next gives me this error:
Reason: Props must be returned as a plain object from getServerSideProps: `{ props: { ... } }` (received: `[object Array]`).
If instead of returning {}, I return
{
props: {}
}
the code works all right. Does anyone know why this is happening?
I'm using a custom _app.jsx file.
In the documentation, it's clearly mentioned that the props argument is optional:
This is actually intended. If you were using TypeScript, return {} would have thrown you error as GetServerSidePropsResult is defined like this here:
export type GetServerSidePropsResult<P> =
| { props: P | Promise<P> }
| { redirect: Redirect }
| { notFound: true }
It means that any one of props, redirect, notFound needs to be present in the returned object. Perhaps you can create an issue at their GitHub (and maybe a PR) to fix the documentation.
As mentioned by #tromgy, it was just the documentation that is unclear.
I am new to Vue.js and experiencing an issue with Vuex modules and Axios. I have a "post" component that retrieves a slug from the router and fetches data with Axios which is then retrieved with Vuex Getters.
I am able to retrieve data successfully but then I still see this error on my DevTools, "TypeError: Cannot read property 'name' of undefined"
Due to this error I am not able to pass this.post.name to Vue-Meta.
Codes
Post.vue
computed: {
...mapGetters(["post"]),
},
mounted() {
const slug = this.$route.params.slug;
this.fetchPost({ slug: slug });
},
methods: {
...mapActions(["fetchPost"]),
/store/modules/post.js
const state = {
post: [],
};
const getters = {
post: (state) => {
return post;
}
};
const actions = {
async fetchPost({ commit }, arg) {
try {
await axios.get("/post/" + arg.slug).then((response) => {
commit("setPost", response.data);
});
} catch (error) {
console.log(error);
}
},
};
const mutations = {
setPost: (state, post) => (state.post = post),
};
export default {
state,
getters,
actions,
mutations,
};
Your getter is utterly wrong: a state getter is supposed to be a function that takes in the entire state as a param and retrieves whatever you're interested in from it. Your version...
const getters = {
post: (state) => {
return post;
}
};
...takes in the state as a param but doesn't use it. Instead, it returns a variable (post) which has not been defined in that context.
Which will always return undefined, regardless of current value of state.post.
And, as you already know, JavaScript can't access property 'name' of undefined.
To get the current value of state.post, use:
const getters = {
post: state => state.post
}
Or
const getters = {
post: (state) => { return state.post; }
}
... if you fancy brackets.
Also, out of principle, I suggest initializing your post with an empty object {} instead of an empty array [].
Changing variable types as few times as possible is a very good coding habit, providing huge benefits in the long run.
Edit (after [mcve])
You have a bigger problem: the import from your axios plugin returns undefined. So you can't call get on it. Because you wrapped that call into a try/catch block, you don't get to see the error but the endpoint is never called.
I don't know where you picked that plugin syntax from but it's clearly not exporting axios. Replacing the import with import axios from 'axios' works as expected.
Another advice would be to namespace your store module. That's going to become useful when you'll have more than one module and you'll want to specifically reference a particular mutation/action on a specific module. You'll need to slightly change mapActions and mapGetters at that point.
See it working here.
I made a fake api call to my json file with axios. I get a promise back from the function where i can get my data from. but i don't want that. I want to receive the data from the function.
my code now: products.js
export default {
getAllProducts(axios) {
return axios.get('fakedb.json').then(response => {
return response.data;
});
}
}
the view file: a product.vue file
import productController from '~/data/controllers/product';
export default {
data() {
return {
products: productController.getAllProducts(this.$axios).then(res => this.products = res)
}
},
}
but this is not what i want to achieve.
what i want to achieve is this code in my product.vue file:
import productController from '~/data/controllers/product';
export default {
data() {
return {
products: productController.getAllProducts(this.$axios)
}
},
}
i want to receive the data without having to handle the promise in the view file. any solution how to return my data in the products.js file?
if i do a normal return from the products.js file like this it works fine:
export default {
getAllProducts(axios) {
return [
{
"name": "Product1",
"price": 9.75
},
{
"name": "Product2",
"price": 10.75
}
]
}
}
But i want it to go with axios
Since you have a .vue-file, I assume that this is a single-page vue component, right? And therefore you use vue-cli or webpack. I therefore assume that you can use async/await syntax.
Retrieving data from axios is asynchronous, because you basically cannot know how long it takes for it to retrieve the data over the network. And this kind of situation is what async/await is for.
So make the functions async:
products.js
export default {
async getAllProducts(axios) {
const response = await axios.get('fakedb.json');
return response.data;
}
}
product.vue:
import productController from '~/data/controllers/product';
export default {
data() {
return {
products: [],
};
},
async mounted: {
this.products = await productController.getAllProducts(this.$axios);
}
}
I do not think you can make the data function asynchronous, so return an empty data object (I have assumed that it is an array), and then use the mounted hook to retrieve data.
You can't. A function returns immediately and there is nothing meaningful for it to return if you don't want a promise, since loading won't have begun yet. This is the problem that promises solve to begin with. It's a bad pattern to make an async call into your data to begin with, though. Use this pattern instead:
data() {
return {
products: null
}
},
methods: {
getAllProducts() {
return axios.get('fakedb.json').then(response => {
this.products = response.data;
});
}
},
created() {
this.getAllProducts();
}
The async call is abstracted out into the created hook, and when it's resolved it will set the data accordingly.
Here's a little demo
I am trying to separate my axios calls from my main vue instance by importing them instead of calling them directly in the created hook.
I have this in a separate file called data.js
import axios from 'axios'
export default{
myData() {
return axios.get(`http://localhost:8080/data.json`)
.then(response => {
// JSON responses are automatically parsed.
return response.data;
})
.catch(e => {
return this.myErrors.push(e)
});
},
And in my vue instance I have the following:
import myDataApi from '#/api/data.js'
export default {
name: 'app',
components: {
myDataApi, // not sure if this is correct
},
data: function () {
return {
myInfo: '',
}
},
created() {
this.myInfo = myDataApi.myData();
console.log('this.myInfo= ', this.myInfo)
},
I am trying to populate myInfo with the json called by myData. This returns [object Promise] in Vue devtools and the as PromiseĀ {<pending>} in the console.
All the data I need is inside that PromiseĀ {<pending>} in an array called [[PromiseValue]]:Object so I know it is working, I just need to know the correct way implementing this.
I don't have a development environment enabled to test this at the moment, but I do notice that you are trying to assign a variable the moment that the component is initialized. This object is a promise, but you're not handling the promise after it is resolved inside the component where you have imported it.
I would recommend trying to handle the promise inside of the actual component, something like:
import myDataApi from '#/api/data.js'
export default {
name: 'app',
components: {
myDataApi, // not sure if this is correct
},
data: function () {
return {
myInfo: '',
}
},
created() {
myDataApi.myData()
.then((data) => {
this.myInfo = data
console.log('this.myInfo= ', this.myInfo);
});
.catch((e) => handleError) // however you want to handle it
},
Just to add to #LexJacobs answer. I omitted the parenthesis around data in .then() as seen below. Vue was squawking about data not being available even though it was. This solved that problem, although to be honest I don't know why.
myDataApi.myData()
.then(data => {
this.dataHasLoaded = true;
this.myInfo = data;
})
.catch(e => {
this.myErrors.push(e)
});
I need to use masterKey inside my angular2 app, but I can't pass it to initialize function and I can't google out why.
From package.json: "parse": "~1.9.2".
Initialization:
import {Parse} from '~/node_modules/parse/dist/parse';
#Injectable()
export class TFCloudService {
constructor() {
this.parse = Parse;
Parse.initialize(appConfig.parse.appId, null, appConfig.parse.masterKey);
Parse.serverURL = appConfig.parse.clientServerUrl;
Parse.liveQueryServerURL = appConfig.parse.liveQueryServerURL;
}
}
Error source:
this.edittedUser.save(null, {useMasterKey: true})
.then((user) => {
console.log(user);
});
Error text:
Error: Cannot use the Master Key, it has not been provided.
appConfig.parse.masterKey works fine, I checked that line with hard-coded key too, but got the same result.
Actually guessed the right way to pass that key:
Parse.initialize(appConfig.parse.appId);
Parse.masterKey = appConfig.parse.masterKey;