Vue application request wrong Axios baseURL - vue.js

I try to create a baseURL from .env.local, but in request I get http://localhost:8083/Contracts/users insted of https://api.EXAMPLE.dev/api/users.
I use npm run serve -> http://localhost:8083
Any suggestion, please?
.env.locale
VUE_APP_ENDPOINT="https://api.EXAMPLE.dev/api"
main.js
import axios from "axios";
axios.defaults.baseURL = process.env.VUE_APP_ENDPOINT;
Component.vue
created: function() {
axios
.get("/users")
.then(response => {
this.items = response.data;
})
.catch(error => {
console.log(error);
});
},

Try writing
axios.defaults.baseURL = process.env.VUE_APP_ENDPOINT || "https://api.EXAMPLE.dev/api"
And for Component.vue file
created: function() {
axios({
url: "/users"
})
.then(response => {
this.items = response.data;
})
.catch(error => {
console.log(error);
});
}
Check if this works. May be that can be reason that process.env is not giving correct value.

Was no problem with the code, after a restart it worked.
npm run serve

Related

Mock .get() Function using Jest on VueJS

I am trying to mock a GET request to get some Posts using the ID. This is the code I am trying to mock:
getPost() {
this.refreshToken();
http
.get(`/posts/${this.$cookie.get('postid')}`, {
headers: {
"Authorization": `Bearer ${this.$cookie.get('token')}`,
"Content-type": "application/json",
},
})
.then((response) => {
this.post = response.data;
})
.catch((error) => {
console.log(error.response);
});
}
This is my attempt at a test:
import {getPost} from '#/views/Post.vue'
import axios from 'axios';
jest.mock('axios');
describe('get Post by ID', () => {
afterEach(() => {
jest.resetAllMocks();
});
it('should return empty when axios.get failed', async () => {
const getError = new Error('error');
axios.get = jest.fn().mockRejectedValue(getError);
const actualValue = await getPost();
expect(actualValue).toEqual(new Map());
expect(axios.get).toBeCalledWith('/posts/postid');
});
it('should return users', async () => {
const mockedUsers = [{ postID: 1 }];
axios.get = jest.fn().mockResolvedValue(mockedUsers);
const actualValue = await getPost(['1']);
expect(actualValue).toEqual(mockedUsers);
expect(axios.get).toBeCalledWith('/posts/postid');
});
})
The error I am getting is:
TypeError: (0 , _Post.getPost) is not a function
I am not sure what to do, and any help would be super appreciated. Thanks!
Assuming you have getPost() defined in the Post component's methods, you can't use named imports to access getPost. Instead, you'll have to mount the component, and use the wrapper's vm:
// Post.spec.js
import { shallowMount } from '#vue/test-utils'
import Post from '#/views/Post.vue'
it('...', () => {
const wrapper = shallowMount(Post)
await wrapper.vm.getPost()
expect(wrapper.vm.post).toEqual(...)
})
Also make sure to return the axios call in getPost() so that it could be awaited:
// Post.vue
export default {
methods: {
getPost() {
this.refreshToken();
👇
return http.get(/*...*/)
.then(/*...*/)
.catch(/*...*/);
}
}
}

Mocking axios in Jest returns axios is not defined

I have seen similar questions but they dont actually address what am looking for.
so am using using axios globally in app.js for my vue app like window.axios=require('axios')
then in auth.js i have this
export function login(credentials){
return new Promise((res,rej) => {
axios.post('/api/auth/login', credentials)
.then((response) => {
res(response.data);
})
.catch((err) => {
rej("Wrong email or password");
})
});
}
which works fine on the login page
however in my test script
jest.mock("axios", () => ({
post: jest.fn(() => Promise.resolve({data:{first_name:'James','last_name':'Nwachukwu','token':'abc123'}}))
}));
import axios from 'axios'
import {login} from '../helpers/auth'
it("it logs in when data is passed", async () => {
const email='super#gmail.com'
const password='secret';
const result=await login({email,password});
expect(axios.post).toBeCalledWith('/api/auth/login',{"email": "super#gmail.com", "password": "secret"})
expect(result).toEqual({first_name:'James','last_name':'Nwachukwu','token':'abc123'})
})
shows axios is not defined
but if i change auth.js to
import axios from 'axios'
export function login(credentials){
return new Promise((res,rej) => {
axios.post('/api/auth/login', credentials)
.then((response) => {
res(response.data);
})
.catch((err) => {
rej("Wrong email or password");
})
});
}
test passes. how do i run the test without having to import axios on each vue file
I had the same problem just now. I am also including axios via window.axios = require('axios'); in my app.js.
The solution is to set your axios mock on window.axios in your test. So instead of this (incorrect):
axios = {
post: jest.fn().mockName('axiosPost')
}
const wrapper = mount(Component, {
mocks: {
axios: axios
}
})
When your component code calls axios.whatever it is really calling window.axios.whatever (as I understand it), so you need to mirror that in your test environment:
window.axios = {
post: jest.fn().mockName('axiosPost')
}
const wrapper = mount(Component, {
mocks: {
axios: window.axios
}
})
And in your test:
expect(window.axios.post).toHaveBeenCalled()
The above method works fine until you want to chain then to it. In which case you need to set your mock up like this:
window.axios = {
get: jest.fn(() => {
return {
then: jest.fn(() => 'your faked response')
}
}),
}
You don't need to pass it into the component mock though, you can just mount (or shallowMount) the component as usual

How to delete data using Vue.axios.delete()

I am new to vuejs. I am having trouble deleting json data from a fakeserve by using axios.delete().
I tried doing this :-
axios.delete('http://localhost:3000/users/', {params: {id: this.idToDelete} })
.then((response) => {
console.log(response)
}, (error) => {
console.log(error)
})
This is my html:-
<v-text-field v-model="idToDelete" type="number" hide-details outline
label="Enter Id to delete"></v-text-field>
<v-btn #click="userIdtoDelete()" color="error">Delete</v-btn>
This is my javascript (src/views/pages/Delete.vue):
import Vue from 'vue'
import axios from 'axios'
import VueAxios from 'vue-axios'
Vue.use(VueAxios, axios)
export default {
data () {
return {
idToDelete: ''
}
},
methods: {
userIdtoDelete () {
axios.delete('http://localhost:3000/users/', {params: {id: this.idToDelete} })
.then((response) => {
console.log(response)
//alert('response = ' + response)
}, (error) => {
console.log(error)
//alert('error = ' + error)
})
}
}
}
My code is in https://github.com/boidurja/users.git
And fakeserver is in https://github.com/boidurja/fakeserver.git
When I click the delete button data is not getting deleted and I am getting the following error message:-
DELETE http://localhost:3000/users/?id=3 404 (Not Found)
JSON Server automatically creates routes in a RESTful format, eg
GET /users
GET /users/1
POST /users
PUT /users/1
PATCH /users/1
DELETE /users/1
So with that in mind, you should be using
axios.delete(`http://localhost:3000/users/${encodeURIComponent(this.idToDelete)}`)
.then(res => { console.log(res) })
.catch(err => { console.error(err) })
I think your issue is that you are calling a function inline with () vue does this for you, try
<v-btn #click="userIdtoDelete" color="error">Delete</v-btn>
I think you are triggering the function twice.
In addition, you can try instead of using v-model to catch the id directly in the function like userIdtoDelete($event.target.value)

Vue Axios local stored token is undefined

In Vue I am building a small Userprofile page. It is build on token-authentication using Axios. When mounting this page the token is undefined.
with login a token is placed in the localStorage.
The Axios Get request is build outside the Vue component
Api.js
import axios from 'axios'
export default () => {
return axios.create({
baseURL: `http://localhost:8081/`
})
}
Get request
import Api from '#/services/Api'
let config = {
headers: {
'Content-Type': 'application/json',
'Authorization': localStorage.getItem('token')
}
}
export default {
index () {
return Api().get('user/profile', config)
}
}
Vue
<script>
export default {
data: () => ({
user: {}
}),
mounted () {
this.user = UserProfileService.index
console.log(UserProfileService.config)
}
}
</script>
There are many advices and I tried them all. With tics, with commas etc. Who sees the big picture?
Use a request interceptor to set the Authorization header:
// Api.js
export default () => {
const instance = axios.create({
baseURL: `http://localhost:8081/`
})
instance.interceptors.request.use(function (config) {
const token = localStorage.getItem('token')
if (token) {
config.headers.Authorization = `Bearer ${token}`
}
return config
}, function (error) {
// Do something with request error
return Promise.reject(error)
})
return instance
}
I added the code from digital drifter, and solved the problem (with help) with changing the mounted function in Vue.
mounted () {
console.log('mounted')
UserProfileService.index()
.then((res) => {
this.user = res.data
})
}

VueJS / ExpressJS (Backend) - Getting data from an API

I'm learning VueJS / Express and I'm trying to display data from an external API onto my page. I'm using Express as the API Calls require headers + I believe its safer to keep it separate from Vue.
Here is my Express
app.get('/summoner', function(request, response) {
axios.get('https://euw1.api.riotgames.com/lol/summoner/v3/summoners/by-name/XXXXXXXX', {headers: headers})
.then(response => {
console.log(response.data)
})
.catch(error => {
console.log(error)
})
})
Here is my Vue code:
import axios from 'axios'
export default {
name: 'summoner',
data () {
return {
summoner: [],
errors: []
}
},
created () {
console.log('Created')
axios.get('/api/summoner')
.then(response => {
console.log('Hit me')
this.summoner = response.data
})
.catch(e => {
this.errors.push(e)
console.log(e)
})
}
}
The console.log(response.data) is showing me the object I expect which is:
{ id: XXXXXXXX,
accountId: XXXXXXXX,
name: 'XXXXXXXX',
profileIconId: XXXXXXXX,
revisionDate: XXXXXXXX,
summonerLevel: XXXXXXXX }
The console.log('Hit Me') is never fired
The console.log('Created') is fired on page load.
Nothing I seem to try allows me to display any of the object using Vue e.g:
{{ summoner.id }}
Just to add, I have configured a proxy in webpack which forwards the below requests to Express. As far as I can tell, this is working as each time I refresh the page, I see the ExpressJS console.log(response.data) fire
Could anyone help?
Thanks!
In your express code you do not return the repsonse (which you also override in the axios response). Try changing it to
app.get('/summoner', function(request, res) { // <--- careful here is a change
axios.get('https://euw1.api.riotgames.com/lol/summoner/v3/summoners/by-name/XXXXXXXX', {headers: headers})
.then(response => {
console.log(response.data)
return res.status(200).send(response.data);
})
.catch(error => {
console.log(error)
return res.status(400).send(error);
})
})
I actually resolved this by doing:
res.json([response.data])
In the ExpressJS side of things.
I also had to use response.data[0] within Vue.