Vue can't redirect to the same page - vue.js

Im currently, making a form, where I have a button, "Save and add another" , what I do, I validate the data and if saving is a success I'm trying to redirect the user to the same page but its not working(example: from this page http://localhost:8080/#/add_new_entity to this page http://localhost:8080/#/add_new_entity).
So far i've tried this:
this.$router.push('/add-new-entity')
i get this error:
NavigationDuplicated {_name: "NavigationDuplicated", name:
"NavigationDuplicated", message: "Navigating to current location
("/add_new_entity") is not allowed", stack: "Error↵ at new
NavigationDuplicated (http://loca…voker
(http://localhost:8080/js/app.js:135303:14)"}
And i know i could just refresh, but i have set in my router/index.js this: router.replace({ path: '/dashboard', redirect: '/dashboard' }) so every time the page is refreshed it automaticaly redirects to /dashboard.
Any solutions out there?
EDIT: I still havent found a solution for that. Yes this catches the error this.$router.push("/add-new-entry").catch(err => {}) so I dont get the error message and can handle it, but I'm still not able to redirect to the same page.

Just do this.$router.push("/add-new-entry").catch(err => {})

Related

Vue Router doesn't update page when named variable is manually changed

I have the following definition in my Vue router
{
path: '/search/entity/:entity',
name: PageType.SEARCH_RESULTS_ENTITY_ID,
component: Entity
}
If a user types in id3 into a search box, they end up at /#/search/entity/id3 either shows the data or a "Not Found" exception.
The challenge I'm facing is that if one of my users manually changes the URL to /#/search/entity/id4 the page stays on 3 and doesn't update to 4's content. The only way to get that to happen is with a full page refresh.
I tried this hack
window.addEventListener("hashchange", (e: HashChangeEvent) => {
router.push({
path: window.location.hash.substr(1),
});
})
but it gives this error:
NavigationDuplicated: Avoided redundant navigation to current location: "/search/entity/id4
How can I get Vue to detect and update the page when these changes happen? Note that I have this schema on a large number of pages, so I'm looking for a global project solution.

Vue update state after router push

In my application I have a page with params I'd like to redirect the user to a 'destination' page after they login. I can do a $router.push like this:
this.$router.push({
name: "foo",
params: {
title: "Hello",
message: "World!"
}
});
The user has just been logged in programatically at this point and I'd like the state of the root component to update so that, for example, the "Logout" button appears. I can refresh the page with this.$router.go() but then I'd need some logic to prevent infinite refreshes. I don't want to refresh from the 'destination' page because it's a component I use elsewhere. I don't think I can reload the window to that destination because I need to pass params.
Is there a way I can $router.push() with a reload, or refresh the App.vue component state without a reload?

How do I detect the page the user came from in vue.js when the page opens in a new tab?

I've got an interesting problem in my vue.js application and I don't know how to solve it.
We've got a "my listings" page that shows a grid of listings that the user created. When they click on one, it takes them to the listing details page. It opens this page in a new browser tab.
What we want to do is add a new component to the top of the page that shows the user the stats on their listing. But we want this component to show up ONLY when they come to the listing details page from the My Listings page. There are other ways of getting to the Listing Details page and we don't want the stats component to show up when they come from these other ways.
I would think this could be handled in the router. I tried seeing if I could detect that the user was coming from the My Listings page from the "from" parameter in the beforeEach(...) method of the router. I did this:
router.beforeEach(async (to, from, next) => {
console.log('from=', from);
console.log('to=', to);
});
When it prints the from parameter, I get this:
to= {
fullPath: "/"
hash: ""
matched: []
meta: {}
name: null
params: {}
path: "/"
query: {}
}
It contains no information about where it came from. I'm guessing this is because it opens the Listing Details page in a new tab. So I can't use the router to tell where the user came from.
Instead, I resorted to using localStorage:
On the My Listings page:
<v-btn :href="`/listings/${listing.listingId}`" target="_blank" #click="saveFromMyListings();">View Listing</v-btn>
...
saveFromMyListings() {
localStorage.setItem('from-my-listings', true);
},
On the Listing Details page:
async created () {
this.fromMyListings = localStorage.getItem('from-my-listings') === 'true';
localStorage.setItem('from-my-listings', false);
},
So long as I set the 'from-my-listings' item in localStorage to false immediately after I use it to determine that the user came from the My Listings page, it works. That way, it is ONLY set if the user comes from the My Listings page, and never set if the user comes from anywhere else.
The problem with this method is that if the user refreshes the page, the stats disappear. Obviously, this is because created() reruns and this time 'from-my-listings' is removed from localStorage. I can fix this by not setting it to false in created() once it's used, but then where do I remove it in such a way that it's guaranteed to be removed no matter how the user leaves the page (entering a new url directly in the browser, closing the browser, computer loses power, etc.)?
Is there some other hook in vue.js besides created() that runs only once (when the user first visits the page) but not on subsequent loads (like refresh)? Is there a way to pass props to a component in the router based on the state of localStorage that won't have to be passed again on refresh? What other solutions might there be to this problem?
You could use query parameters. You'd have to change the links to something like this:
yourapp.com/listing-detail/333?from=list
then in the created function you can check window.location.search for the from value

Nuxt 404 error page should redirect to homepage

I am looking for a way to always redirect to homepage when a page doesn't exist using Nuxt.Js.
Our sitemap generation had some problems a few days back and we submitted wrong urls that do not exist. Google Search Console shows a big number of 404 and we want to fix them with 301 redirect to homepage.
I tried this
created() {
this.$router.push(
this.localePath({
name: 'index',
query: {
e: 'er'
}
})
)
}
and although the page redirects to homepage successfully I think Google will have problems with this since the pages initially renders with 404.
I also tried this
async asyncData({ redirect }) {
return redirect(301, '/el?e=rnf')
},
but didn't work (same with fetch)
Any ideas on a solution to this?
Never redirect to home if page is not found as you can see in this Google's article: Create custom 404 pages
instead, redirect to 404 error page
Just use error
async asyncData({ params, $content, error }) {
try {
const post = await $content('blog', params.slug).fetch()
return { post }
} catch (e) {
error({ statusCode: 404, message: 'Post not found' })
}
}
do not forget to creat an error page in layout folder error.vue
You are able to create a default 404-page in nuxt - just put a file with a name _.vue in your ~/pages/ dir. This is your 404-page :)
or you can use another method to create such page: https://github.com/nuxt/nuxt.js/issues/1614 but I have not tried it
Then add a simple 404-redirect-middleware to this page:
// !!! not tested this code !!!
middleware: [
function({ redirect }) {
return redirect(301, '/el?e=rnf')
},
],
Personally I would advise to create a 404 page which provides a better user experience in comparison to being redirected to a homepage and potentially being confused about what happened.
In order to create a custom error page, just create error.vue file in the layouts folder and treat it as a page. See the official documentation. We've implemented this plenty of times and Google has never complained about it.
Still, gleam's solution is clever and if it serves the purpose, very well. Just wanted to point out another solution.
If you need to provide custom routes to your users like domain.com/<userID>
then putting a file with a name _.vue in your ~/pages/ directory will not work, because you'll need it for your custom user routes.
For maximum flexibility use the layouts folder as mentioned by Dan
Create a file called _.vue at pages directory with content:
<script>
export default {
asyncData ({ redirect }) {
return redirect('/')
}
}
</script>

Aurelia cancel navigation in navigation strategy

I have a login route that will redirect the user to an external Open ID Connect login page. Once there, if the user clicks the back button, they hit the same route that redirected them, thus being redirected again. Is there a way to cancel Aurelia's navigation or prevent the current route from being remembered in the history?
config.mapRoute({
name: "login",
nav: false,
// If I exclude the module id, I get the desired behavior but errors are thrown from Aurelia.
moduleId: "components/login/login",
route: "login",
navigationStrategy: (instruction: NavigationInstruction) => {
// This promise constructs the redirect url then sets the window.location.href.
// Unfortunately, Aurelia seems to be finishing its business before the page is redirected because this login route is recorded in history.
return this.userManager.signinRedirect();
}
});
I know its been a while so you probably found an answer elsewhere, but you can try
router.navigate('new url', { replace: true });