I am creating an application where I have a list of users, when I click on a single user, it takes me to that specific users profile (Profile.vue). I am using ASP.NET Core API with Vue.js as my front end. My API is working so when I click on the user, I am able to see the data coming from my database using Chrome dev Tools and Postman. When I open Vue Dev Tools in Chrome, I see that the data is "undefined". For example, I am just trying to get the users firstName to display so I know that its working.
This is how I am routing my page from the list of users to a specific users profile
methods: {
editItem(lastName) {
this.$http.get(`http://localhost:61601/api/GetInquiry/${lastName}`)
this.$router.push({ path: `/Profile/${lastName}` })
},
async GetAllInquiries() {
this.loading = true
try {
this.records = await api.GetAllInquiries()
} finally {
this.loading = false
}
},
Once I am routed, Here is my Profile.Vue that will show the users information
<template>
<div>
<h2>Student Info</h2>
Student Name: {{ records.firstName }}
<br />
</div>
</template>
<script>
import api from '../store/api.js'
export default {
data() {
return {
records: {
firstName: this.firstName
},
}
},
async created() {
this.GetInquiriesByUser()
},
methods: {
async GetInquiriesByUser() {
this.loading = true
},
post: function () {
this.$http.get('http://localhost:61601/api/inquiry', {
firstName: this.firstName
})
}
}
}
</script>
API.js
import Vue from 'vue'
import axios from 'axios'
const client = axios.create({
baseURL: 'http://localhost:61601/api/',
json: true
})
export default {
async execute(method, resource, data) {
return client({
method,
url: resource,
data,
}).then(req => {
return req.data
})
},
GetAllInquiries() {
return this.execute('get', '/Inquiry')
},
GetInquiriesByUser() {
return this.execute('get', '/GetInquiry/')
},
create(data) {
return this.execute('post', '/', data)
},
update(id, data) {
return this.execute('put', `/${id}`, data)
},
delete(id) {
return this.execute('delete', `/${id}`)
}
}
GetInquiryByUser Controller
[Route("api/[controller]")]
public class GetInquiryController : BaseController
{
private GetInquiryByUser manager;
public GetInquiryController(IConfiguration config) : base(config)
{
manager = new GetInquiryByUser(config);
}
[HttpGet("{lastName}")] //api/GetInquiry/yourlastname
public IEnumerable<InquiryModel> Get([FromRoute]string lastName)
{
return manager.GetInquiriesByUser(lastName);
}
}
The Inquiry contoller gets the list of all users and my GetInquiryByUser is passing the lastName to get that specific users profile. (eventually I will pass a unique id, just testing for now)
I am using hash mode for vue routing as well. At first I was confused on what mode I was using and I had a combination of history and hash, but I think I am all hash mode now.
If someone can point me into the right directions, that would be awesome! Please let me know if I need to porvide more details.
Related
I am working on error handling for an application built in Vue/Vuetify. I am using external pagination for a datatable that links to an API that only allows so many hits in a period of time. Because of that, I'm trying to pass through and display an error of "Too Many Requests" on the front end for users when they hit that limit.
The issue I'm having though is passing that error from the backend server to the frontend. When it errors on the front end, it just gives a 500 error. However, the server log is giving me the actual error happening. How can I get that to pass? Below is the relevant javascript code from the server and the front end.
For note: I've been using eventbus to display errors throughout the project. But up until now, I haven't had to pass any from the back to front.
Backend Server
module.exports = {
async find(ctx) {
var page = ctx.query.page;
var key = '';
var locale = ({ location: '', location_type: '', page: page });
const sdk = require('api')('#');
try {
var response = await sdk.auth(key)['grants_funders'](locale);
}
catch (err) {
console.log(err);
}
;
// .then(res => console.log(res))
// .catch(err => console.error(err));
// console.log(response);
return response
}
};
FRONTEND
export default {
name: "Search",
components: {},
props: ["funderDirectories", "serverItemsLength"],
data() {
return {
page: 1,
usericon: usericon,
greentick: greentick,
listicon: listicon,
training: training,
keyword: null,
funderHeaders: [
{ text: "Organization", value: "funder_name" },
{ text: "City", value: "funder_city" },
{ text: "Country", value: "funder_country" },
{ text: "Count", value: "grant_count" },
],
myloadingvariable: false,
pageCount: 1,
itemsPerPage: 25,
};
},
watch: {
page() {
Vue.$funderService.find({ page: this.page }).then((res) => {
this.funderDirectories = res.data.rows;
this.serverItemsLength = res.data.total_hits;
});
},
},
methods: {},
computed: {
filteredFunderDirectories() {
if (!this.keyword) {
return this.funderDirectories;
}
return this.funderDirectories.filter(
(q) =>
q.funder_name.toLowerCase().indexOf(this.keyword.toLowerCase()) !== -1
);
},
},
};
Ultimately figured it out. added the following to the backend catch
return ctx.send({errorStatus:"Too Many Requests. Please Wait"},429)
And I was able to call
I am Implementing Deeplink in ionic 4 application. Application in getting launched but deeplink plugin always returns false;
app.routing.ts:
{
path: 'viewdiary/:id/public',
loadChildren: () => import('./pages/viewdiary/viewdiary.module').then( m => m.ViewdiaryPageModule)
},
app.compoent.ts:
setupDeepLink(){
this.deeplinks.route({
'/viewdiary/:id/public': 'viewdiary/:id/public'
}).subscribe((match)=>{
console.log('deeplink matched', match);
const internalPath = `${match.$route}/${match.$args['id']}/${match.$route}`;
console.log(internalPath);
this.zone.run(()=>{
this.general.goToPage(internalPath);
});
},
nomatch=>{
// nomatch.$link - the full link data
console.error("Got a deeplink that didn't match", nomatch);
})
};
My Public diary Page link is 'https://www.example.com/diary/12542/public';
it looks like a routing issue tried many thing changes names but nothing works. I am clueless what going wrong.
Figured out how to achieve it with the help of Another Answer on Stackoverflow
import { Platform, NavController } from '#ionic/angular';
constructor(public navCtrl: NavController){}
this.deeplinks.routeWithNavController(this.nav, {
'/viewdiary/:diary/:id/:public': 'viewdiary'
}).subscribe((match) => {
console.log('success' + JSON.stringify(match));
}, (noMatch) => {
console.log('error' + JSON.stringify(noMatch));
});
For me, this approach did not work either. So, in my application I handle deep links as follows:
const {App}: { App: AppPlugin } = Plugins;
...
export class AppComponent {
private setupDeepLinks(): void {
App.addListener('appUrlOpen', (data: any) => {
this.ngZone.run(() => {
// Example url: https://my-domain.com/tabs/tab2
// slug = /tabs/tab2
const slug = data.url.split('my-domain.com').pop();
if (slug) {
this.router.navigateByUrl(slug);
}
});
});
}
}
Or you can implement your own more complex logic inside the listener if needed
I am Working at a VueJS Webapplication with a c# WebAPI in the background. I made already one endpoint but I cant get it to work. The body of the response is always null. When i check the debug section on the network tab, i can see the message i want to get in the preview section, but I cant get it to show on the page.
VueJS component:
<template>
<div class="dashboard">
<button type="button" id="get-joke" #click="fetchAPIData">Get a Joke!!</button>
<div v-if="responseAvailable == true">
<hr>
<p>
<i>{{result}}</i>
</p>
<hr>
</div>
</div>
</template>
<script>
export default {
name: 'Dashboard',
props: {
msg: String
},
components: {
},
Data() {
result: null,
responseAvailable: null
},
methods: {
fetchAPIData() {
this.responseAvailable = false;
fetch("https://localhost:44322/api/values", {
"mode": "no-cors",
"method": "GET",
})
.then(response => {
alert(response); //checking if i get something
return response.json();
})
.then(response => {
this.result = response.body;
this.responseAvailable = true;
})
.catch(err => {
var error = err;
return error;
});
}
}
};
</script>
C# API Controller (returning a JSON string of a list of Objects) :
using System;
using Microsoft.AspNetCore.Mvc;
using MO_Backend.Services;
using MO_Backend.APIServices;
namespace MO_Backend.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
private readonly O_UserService _oUserService;
public ValuesController(O_UserService oUserService)
{
_oUserService = oUserService;
}
// GET: api/values
[HttpGet]
public String Get()
{
OnlineCheckService occ = new OnlineCheckService(_oUserService);
return occ.GetRobotState();
}
}
}
Does anyone know what im doing wrong or an alternative to what im trying to do?
The problem is the no-cors mode in your http request. This results in an opaque request, which means you get a response, but you cannot use the data. You need to use cors and set the response headers in your backend accordingly.
I am trying to use Vue.js for my front end to call Stripe and create a token which then is sent to my backend. I have tested everything using plain HTML/JS and it all works fine, my issue comes in trying to use Vue.js I think my issue might be in how I am binding the stripe public key. Below is my code, and I have zero output to speak of, I get just redriected to the same page but wth ? at the end of the URL. Nothing else, console shows nothing and no error message or anything send to my back end.
template code
There is more but not related
<div class="col-md-8">
<card class='stripe-card col-md-8'
:class='{ complete }'
:stripe='stripeKey'
:options='stripeOptions'
#change='complete = $event.complete'
/>
<button class='pay-with-stripe' #click='pay' :disabled='!complete'>Submit Payment Details</button>
<br>
</div>
script section with relavent added
import { Card, createToken } from 'vue-stripe-elements-plus'
import axios from 'axios';
export default {
components: { Card },
data() {
return {
errorMessage: null,
successMessage: null,
complete: false,
stripeKey: process.env.VUE_APP_STRIPE_PUB_KEY,
stripeOptions: {
// see https://stripe.com/docs/stripe.js#element-options for details
hidePostalCode: true
},
current: {
stripe: {
plan: null,
last4: null
}
},
}
},
methods: {
pay () {
createToken().then(result => {
axios.post('/billing/updateCard', {
token: result.token,
})
.then(res => {
if(res.data.success == true) {
this.successMessage = res.data.message
console.log(res.data.message)
}
if(res.data.success == false) {
this.errorMessage = res.data.message // Display error message from server if an error exists
}
})
.catch((err) => {
if(err) console.log(err)
if(err) this.$router.push('/company/settings?success=false')
})
});
}
}
}
</script>
I have checked that the API key is actually in the data value by doing <p>{{ stripeKey }}</p> and seeing the value show up. So yes the key is there and the key is valid (tested copy/paste into my HTML/JS test)
created(){
this.key=process.env.VUE_APP_STRIPE_KEY;
}
try this, i used this piece of code in my project and it worked... the issue maybe is that your key is not yet initialized when card us rendered idk. maybe key isnt issue at all. try this and let me know if works and we will debug it together.
I'm developing a Vue.js app and I'm trying to make a log in system using multiple components.
on my App.vue component (which is the "primary" component and has the nav-bar) there is this button:
<a class="nav-item" v-link="'login'" v-if="!user.authenticated">Login</a>
...
import auth from '../auth'
export default {
data(){
return{
user = auth.user
}
}
}
In one other file (/auth/index.js) I define the "auth" methods as such:
...
user: {
authenticated: false
},
login(email, password) {
axios.post(LOGIN_URL, {
email,
password
}).then((response) => {
this.user.authenticated = true;
this.user = response.data;
router.go('/home');
})
.catch((error)=>{
console.log(error);
});
}
And then I have another component name Login.vue that handles the view for the login template and calls the "auth.login" method with the required params.
The thing is that I want to update the user from App.vue with the value from auth.user AFTER he logs in. How should I do that? Do I have to manage the v-on:click and v-link priorities and come up with a new method?
EDIT:
I'm also trying to use the beforeRouteEnter method by I am not being successful
I managed to find a solution adding this:
watch: {
$route () {
this.user = auth.user
}
},
Following the documentation here