Reputation: 670
How would I go about having a function called with beforeEnter
pass data to the corresponding route component(s)?
The purpose of beforeEnter in this case is to confirm that a valid bearer token is present as a cookie.
Currently, I have beforeEnter
hitting aws api gateway on /verify/auth
, and then the component loads and makes a call to dynamodb on /list/repos
. The thing is, both routes are protected with a builtin AWS api gatewayV2 JWT authorizer, so it's kind of pointless to hit /verify/auth
.
What I would like is to make beforeEnter
hit /list/repos
, leverage the built in JWT authorizer, and load the next page with the data obtained from the api call. If the user isn't properly authenticated, beforeEnter
won't send the user to the route.
So:
rather than
Here's my code. I had a look at a similar question here, but wasn't able to figure it out. passing data to route's component beforeEnter
index.js
let repositories = [];
async function listRepositories(to, from, next) {
var isAuthenticated = false;
console.log("testing listRepositories...");
if (Vue.$cookies.get("Authorization")) {
try {
const response = await fetch(
process.env.VUE_APP_API_GATEWAY_ENDPOINT + "/list/repos",
{
method: "POST",
body: '{"repo_owner": "sean"}',
headers: {
Authorization: Vue.$cookies.get("Authorization")
}
}
);
repositories = await response.json();
console.log(repositories);
if (repositories.message != "Unauthorized") {
isAuthenticated = true;
// return {
// repositories
// };
next();
}
} catch (error) {
console.error(error);
}
}
if (!isAuthenticated) {
console.log("error not authenticated");
to("/");
}
}
const routes = [
{
path: "/",
name: "Login",
component: () => import("../views/Login.vue")
},
{
path: "/repos",
name: "Repos",
// beforeEnter: isAuthenticated,
beforeEnter: listRepositories,
props: repositories => {
{
repositories;
}
},
component: () => import("../views/Repos.vue")
}
];
./views/Repos.vue
<template>
<div id="app" class="small-container">
<repo-table
:repositories="repositories"
/>
</div>
</template>
<script>
import RepoTable from "@/components/RepoTable.vue";
export default {
name: "Home",
components: {
RepoTable
},
data() {
return {};
},
props: {
repositories: {
type: Array
}
}
</script>
./components/RepoTable.vue
<template>
<div id="repository-table">
<table border="0">
<tr>
<th style="text-align:left">Repository</th>
// omitted for brevity
</tr>
<tbody>
<tr v-for="(repo, index) in repositories" :key="repo.repo_name">
<td>
<b>{{ repo.repo_name }}</b>
// omitted for brevity
</td>
</tr>
</tbody>
</table>
</div>
</template>
<script>
export default {
name: "repository-table",
data() {
return {
// repositories: []
};
},
props: {
repositories: {
type: Array
}
},
Upvotes: 7
Views: 4151
Reputation: 63059
beforeEnter
You can pass data from beforeEnter
using route params. When the value of props
is true
, route params will be converted to props:
props: true
Now you just need a param called repositories
and it will be passed as a prop to the destination. In your beforeEnter
, when the user is authenticated you can add that param:
if (repositories.message != "Unauthorized") {
isAuthenticated = true;
to.params.repositories = repositories; // ✅ Adding the data to the param
next();
}
Other fixes:
to('/')
to next('/')
next
in every logic path, for example when there is an error and when neither if
condition is met.next
call it with return
like return next
Another option:
You could also achieve this using the beforeRouteEnter
in-component guard.
Upvotes: 6