I am a beginner. I have a Lumen API. The project runs on http://localhost:8000/. In Postman the API is working fine. Now I want to call the API from a NuxtJs project using Axios. My NuxtJs project is running on http://localhost:3000/.
<template>
<div>
CV List
<v-row v-for="(applicant, i) in applicants" :key="i">
<v-col>
<h1>name: {{ applicant.name }}</h1>
<p>{{ applicant.email }}</p>
</v-col>
</v-row>
</div>
</template>
<script>
import { mapState } from 'vuex'
export default {
async fetch({ store, error }) {
try {
await store.dispatch('applicants/fetchApplicants')
} catch (e) {
error({
statusCode: 503,
message: 'Unable to fetch applicants at this time. Please try again.',
})
}
},
computed: mapState({
applicants: (state) => state.applicants.applicants,
}),
}
</script>
my applicants.js file like this:
import CVService from '#/services/CVService.js'
export const state = () => ({
applicants: [],
applicant: {},
})
export const mutations = {
SET_APPLICANTS(state, applicants) {
state.applicants = applicants
},
}
export const actions = {
fetchApplicants({ commit }) {
return CVService.getApplicants().then((response) => {
commit('SET_APPLICANTS', response.data)
})
},
}
CVService is like this,
import axios from 'axios'
const apiClient = axios.create({
baseURL: `http://localhost:8000`,
withCredentials: false,
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
})
export default {
getApplicants() {
return apiClient.get('/api/authors')
},
}
The console is showing error, 503 (Service unavailable). What causing is the problem?
Related
Login Vue
<template>
<div class="container mt-5">
<div class="row">
<div class="col-md-12">
<div class="col-md-6">
<div class="form-group">
<form #submit.prevent="onSubmit">
<label>Kullanıcı Adı</label>
<input
type="text"
class="form-control"
v-model="userdata.username"
/>
<br />
<label>Şifre</label>
<input class="form-control" v-model="userdata.password" />
<br />
<button class="btn btn-primary">Login</button>
</form>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { reactive } from "vue";
const userdata = reactive({
username: "",
password: "",
});
function loginAction() {
this.$store.dispatch("loginPost", userdata.value);
this.$router.push({ path: "/city" });
}
function onSubmit(event) {
event.preventDefault();
loginAction();
}
</script>
<style></style>
store kısmı import { createStore } from "vuex";
export default createStore({
state: {
cities: [],
user: {},
token: null,
},
getters: {},
mutations: {
setToken(state, token) {
state.token = token;
localStorage.setItem("token", token);
},
setUser(state, user) {
state.user = user;
localStorage.setItem("user", JSON.stringify(user));
},
},
actions: {
async login({ commit }, credentials) {
const response = await fetch("https://localhost:7254/api/Auth/login", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(credentials),
});
const data = await response.json();
if (response.ok) {
commit("setUser", data.user);
commit("setToken", data.token);
}
return response.ok;
},
},
});
store js
import { createStore } from "vuex";
export default createStore({
state: {
cities: [],
user: {},
token: null,
},
getters: {},
mutations: {
setToken(state, token) {
state.token = token;
localStorage.setItem("token", token);
},
setUser(state, user) {
state.user = user;
localStorage.setItem("user", JSON.stringify(user));
},
},
actions: {
async login({ commit }, credentials) {
const response = await fetch("https://localhost:7254/api/Auth/login", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(credentials),
});
const data = await response.json();
if (response.ok) {
commit("setUser", data.user);
commit("setToken", data.token);
}
return response.ok;
},
},
});
router js
import { createRouter, createWebHistory } from "vue-router";
import { city } from "#/components/City.vue";
import { Login } from "#/components/Login.vue";
import { home } from "#/components/Home.vue";
const routes = [
{
name: "login",
path: "/login",
component: Login,
},
{
name: "city",
path: "/city",
component: city,
},
{
name: "home",
path: "/",
component: home,
},
];
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes,
});
router.beforeEach((to, next) => {
// localStorage'daki JWT token'ı ve kullanıcı bilgilerini kontrol edin
const token = localStorage.getItem("token");
const user = JSON.parse(localStorage.getItem("user"));
// JWT token veya kullanıcı bilgisi yoksa, giriş sayfasına yönlendirin
// Eğer zaten giriş sayfasına gidiyorsak, yönlendirmeyi iptal edin
if (!token || !user) {
next({ path: "/login" });
}
next();
});
export default router;
main js
import { createApp } from "vue";
import App from "./App.vue";
import store from "../src/store";
import router from "../src/router";
// eslint-disable-next-line no-unused-vars
import bootstrap from "bootstrap/dist/css/bootstrap.min.css";
createApp(App).use(router).use(store).mount("#app");
Home vue
<!-- eslint-disable vue/multi-word-component-names -->
<template>
<h1>anasayfa Vue</h1>
<city />
<login />
</template>
<script setup>
import city from "#/components/City.vue";
import login from "#/components/Login.vue";
</script>
<style></style>
For example, when the page loads, I want it to go directly to the login page because in my router js file, I wrote the condition that it goes directly to the login page if there is no token and user with beforeEach, but it does not work, it gives this warning console log [Vue Router warn]: Unexpected error while initializing the router: TypeError: next is not a function After filling out and submitting the form, I get the following error Uncaught TypeError: Unable to read undefined properties (reading '$store')
first of all "this" doesn't refer to vue instance ,it refers to loginAction block,use arrow function instead ,secondly due to docs you should use useStore() method to get store in vue 3 Composition api
Im building a datatable and it shows my test-data correctly.
However, after i do my Axios request, it doesnt update the state.tableData variable!
What am I doing wrong here?
I keep seeing a table with the value 'test1', and not 'test2' and 'test3'?
I am using Vue3 with the composition API.
This is the template part:
<template>
<div class="card">
<div class="card-body pt-0">
<Datatable
:table-data="state.tableData"
:table-header="state.tableHeader"
>
<template v-slot:cell-name="{ row: item }">
{{ item.name }}
</template>
</Datatable>
</div>
</div>
</template>
And the JS code:
<script lang="ts">
import { defineComponent, toRefs, reactive, ref, onMounted } from "vue";
import Datatable from "#/components/kt-datatable/KTDatatable.vue";
import axios, { AxiosRequestConfig, AxiosResponse} from 'axios';
export default defineComponent({
name: "listing",
components: {
Datatable,
},
setup() {
interface fieldDefinitions {
name: string;
}
const state = reactive({
tableData: ref<fieldDefinitions[]>([]),
tableHeader: [{
name: "Naam",
key: "name",
sortable: true,
}]
});
function getListings() {
const config: AxiosRequestConfig = {
method: 'get',
url: 'https://myurl',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
};
axios(config)
.then(function (response) {
//state.tableData = response.data.data;
state.tableData = [{'name':'test2'},{'name':'test3'}];
console.log(state.tableData);
})
.catch(function (error) {
console.log(error);
});
}
onMounted(async () => {
getListings()
});
return { state,getListings };
},
});
</script>
Not sure why you have tableData: ref<fieldDefinitions[]>([]), you are assigning state.tableData = [{'name':'test2'},{'name':'test3'}]; not state.tableData = ref([{'name':'test2'},{'name':'test3'}]). But even then, state.tableData.value is not needed since reactive unwraps refs. see docs. So as far as I can tell and reproduce, your code should be working properly to trigger reactivity.
The issue is likely due to your Datatable component is not updating properly.
to add data to the server by axios POST method, I receive 500 HTTP error.
it occurs when the request is made from vuex store.
when the request is form component there isn't any problem.
export
default {
name: 'addCategoury',
data: () => ({
name: '',
src: '',
description: '',
}),
methods: {
async AddCat() {
const newCategory = {
categoryName: this.name,
description: this.description,
imageUrl: this.src,
}
let result = await this.$store.dispatch('AddCategory', newCategory)
if (result.data) {
alert('shode');
} else {
alert('result failed')
}
}
}
}
////////////////////in store js////////////////////
import Vue from 'vue'
import Vuex from 'vuex'
import api from '../services/API'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
categories: []
},
getters: {
},
mutations: {
get_category(state, cat) {
}
},
actions: {
async AddCategory(newCategory) {
try {
let result = await api().post('/category/create',newCategory);
console.log(result)
if (result.data) {
alert('ok')
return result
}
} catch (error){
return error
}
}
},
})
////////////////////in API js////////////////////
import axios from 'axios'
export default () => {
return axios.create({
baseURL: 'https://limitless-lake-55070.herokuapp.com'
})
}
<template>
<v-container class="align-text-center">
<v-form class="form">
<v-container>
<v-row>
<v-col cols="7">
<v-text-field outlined v-model="name" label="name" required>
</v-text-field>
</v-col>
<v-col cols="7">
<v-text-field outlined v-model="src" label="image Source" required>
</v-text-field>
</v-col>
<v-col cols="7">
<v-text-field outlined v-model="description" label="description"></v-text-field>
</v-col>
<v-col cols="12">
<v-btn #click="AddCat">
ADD
</v-btn>
</v-col>
</v-row>
</v-container>
</v-form>
</v-container>
</template>
to add data to the server by axios POST method, I receive 500 HTTP error.
it occurs when the request is made from vuex store.
when the request is form component there isn't any problem.
// in the component
methods:{
async AddCat() {
const newCategory = {
categoryName: this.name,
description: this.description,
imageUrl: this.src,
}
let result = await this.$store.dispatch('AddCategory', newCategory)
if(result.data){
alert('dode');
} else {
alert('result failed')
}} }
// in the store.js
import api from '../services/API'
actions: {
async AddCategory(newCategory) {
try {
let result = await api().post('/category/create',newCategory);
console.log(result)
if (result.data) {
alert('ok')
return result
}
} catch (error){
return error
}
}
},
// API
import axios from 'axios'
export default () => {
return axios.create({
baseURL: 'https://limitless-lake-55070.herokuapp.com'
})
}
So I see you're using $store.dispatch, I am assuming you want to use vue actions. I will explain my code after the solution below:
Your component file looks fine to me, please make sure to add the import file too. It plays a big role in your files too, we won't be able to debug without that.
api.js // would be your file where you're setting the default URL for Axios
import axios from "axios";
export default () => {
return axios.create({
baseURL: "https://limitless-lake-55070.herokuapp.com"
});
};
store.js // Actions object is missing from your question
import api from "../plugins/api";
export const actions = {
async AddCategory(newCat) {
try {
let res = await api().post('/category/create',newCat)
let result = res.status;
if (result == 200 || result == 201) {
alert('ok')
}
} catch(error) {
console.log('dd')
}
},
}
I can't get how to solve problem with POST request.
I am trying implement authorization on my site (via Vuejs,vuex,vue-router, axios).
I will be very pleasure, if you give me some advice.
I searched info on forums , but situation was not the same.
Why 404 (OK)? If OK, why 404?
It means, that server received my data, but can't compare correct this or not?
I have components/pages:
App.vue
<template>
<div id="app">
<div id="nav">
<router-link to="/">Home page</router-link> |
<router-link to="/login">Login</router-link>
<span v-if="isLoggedIn"> | <a #click="logout">Logout</a></span>
</div>
<router-view/>
</div>
</template>
<script>
export default {
name: 'App',
computed : {
isLoggedIn : function(){ return this.$store.getters.isLoggedIn}
},
methods: {
logout: function () {
this.$store.dispatch('logout')
.then(() => {
this.$router.push('/login')
})
}
},
created: function () {
this.http.interceptors.response.use(function (err) {
return new Promise(function (resolve) {
if (err.status === 401 && err.config && !err.config.__isRetryRequest) {
this.$store.dispatch("logout")
resolve()
}
throw err;
});
});
},
}
</script>
LoginAnalytics.vue
Here user must input his mobile phone and password.
<template>
<div>
<form class="login" #submit.prevent="login">
<h1>Sign in</h1>
<label>Mobile</label>
<input required v-model="mobile" type="tel" placeholder="mobile phone"/>
<label>Password</label>
<input required v-model="password" type="password" placeholder="Password"/>
<hr/>
<button type="submit">Login</button>
</form>
</div>
</template>
<script>
export default {
data(){
return {
mobile : "",
password : ""
}
},
methods: {
login: function () {
let login = this.mobile
let password = this.password
this.$store.dispatch('login', { login, password })
.then(() => this.$router.push('/secure'))
.catch(err => console.log(err))
}
}
}
</script>
Vuex store
Here I am creating axios POST requests to server.
import Vue from 'vue';
import Vuex from 'vuex';
import axios from 'axios';
import { API_BASE_URL, TEMPORARY_TOKEN } from '../config';
Vue.use(Vuex);
export default new Vuex.Store({
state:{
trainings: [],
incomings: [],
sources: [],
avgShedule: [],
metro: [],
conversion: [],
avgIncome: [],
status: '',
token: localStorage.getItem('token') || '',
user : {},
},
mutations:{
auth_request(state){
state.status = 'loading'
},
auth_success(state, token, user){
state.status = 'success'
state.token = token
state.user = user
},
auth_error(state){
state.status = 'error'
},
logout(state){
state.status = ''
state.token = ''
},
},
getters:{
isLoggedIn: state => !!state.token,
authStatus: state => state.status,
},
actions:{
login({commit}, user){
return new Promise((resolve, reject) => {
commit('auth_request')
axios({
url: `${API_BASE_URL}/analytics.auth`,
data: user,
method: 'POST',
headers: {
"Content-Type": "application/x-www-form-urlencoded",
}
})
.then(resp => {
const token = resp.data.token
const user = resp.data.user
localStorage.setItem('token', token)
axios.defaults.headers.common['Authorization'] = token
commit('auth_success', token, user)
resolve(resp)
})
.catch(err => {
commit('auth_error')
localStorage.removeItem('token')
reject(err)
})
})
},
logout({commit}){
return new Promise((resolve) => {
commit('logout')
localStorage.removeItem('token')
delete axios.defaults.headers.common['Authorization']
resolve()
})
}
}
},
)
router.
There all refs to components and pages
import Vue from 'vue'
import Router from 'vue-router'
import store from '#/store'
import Analytics from '#/pages/Analytics-test.vue'
import LoginAnalytics from '#/components/LoginAnalytics.vue'
import HomeAnalytics from '#/components/HomeAnalytics.vue'
Vue.use(Router)
let router = new Router({
mode: 'history',
routes: [
{
path: '/',
name: 'home',
component: HomeAnalytics
},
{
path: '/login',
name: 'login',
component: LoginAnalytics
},
{
path: '/secure',
name: 'secure',
component: Analytics,
meta: {
requiresAuth: true
}
},
]
})
router.beforeEach((to, from, next) => {
if(to.matched.some(record => record.meta.requiresAuth)) {
if (store.getters.isLoggedIn) {
next()
return
}
next('/login')
} else {
next()
}
})
export default router
And also main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router';
import store from './store'
import axios from 'axios'
Vue.config.productionTip = false
Vue.prototype.$http = axios;
const token = localStorage.getItem('token')
if (token) {
Vue.prototype.$http.defaults.headers.common['Authorization'] = token
}
new Vue({
store,
router,
render: h => h(App),
}).$mount('#app')
Every time, when I am try login me with correct mobile and password, I received error like this:
Problem was with mistake in API endpoint.
All times I tried call this url:
url: ${API_BASE_URL}/analytics.auth,
But correct is:
url: ${API_BASE_URL}/account.auth.
I am using flask as my backend server.
vuex action is not setting token from local storage state to Axios API call. Please help me with what am I missing. currently I am stuck here, this is related to my previous question which I dint get answer so posting again..
Below is my vuex store code:
Vue.use(Vuex);
export default new Vuex.Store({
state: {
// accessToken: JSON.parse(localStorage.getItem('access_token')) || null,
// refreshToken: JSON.parse(localStorage.getItem('refresh_token')) || null,
accessToken: localStorage.getItem('access_token') || null,
refreshToken: localStorage.getItem('refresh_token') || null,
APIData: '',
},
actions: {
refreshToken(context) {
return new Promise((resolve, reject) => {
console.log(context.state.refreshToken);
getAPI.post('/refresh', {
// refresh_token: context.state.refreshToken,
headers: { Authorization: `Bearer ${context.state.refreshToken}` },
})
.then((response) => {
console.log('New access token granted');
context.commit('updateAccessToken', response.data.access_token);
console.log(context.state.accessToken);
resolve(response.data.access_token);
})
.catch((error) => {
console.log('\'error in refresh:\'', error);
reject(error);
});
});
},
}
Here is an example that I built with a simplified Vuex store and Vue component in order to demonstrate the functionality.
/store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
accessToken: '',
localStorage: window.localStorage
},
getters: {
getTokenFromLocalStorage: state => {
return state.localStorage.getItem('accessToken');
}
},
mutations: {
storeTokenInLocalStorage(state, newToken) {
state.accessToken = newToken;
state.localStorage.setItem('accessToken', newToken);
}
}
})
VuexLocalStorage.vue
<template>
<div class="vuex-local-storage">
<div class="row">
<div class="col-md-6">
<button class="btn btn-secondary" #click="getAccessToken">Get Access Token</button>
<h5>{{ accessToken }}</h5>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
accessToken: ''
}
},
methods: {
getAccessToken() {
this.accessToken = this.$store.getters.getTokenFromLocalStorage;
}
},
created() {
// Store initial access token
this.$store.commit('storeTokenInLocalStorage', 'access-token');
}
}
</script>