Correcting Invalid Route Naming - javascript

I'm currently working on a CRUD application - so far I've created an index route, a show route and create route and have moved on to creating an update method. I've gone ahead and added a route, template and a controller, but whenever I try to click on a link to my new template I receive an error letting me know the following:
This link-to is in an inactive loading state because at least one of its parameters presently has a null/undefined value, or the provided route name is invalid.
I'm linking to the update path through the show page and can confirm that the ID I'm passing into the link-to function exists. This being the case, I think that there's something likely wrong with my route name but can't figure out where I'm going wrong. I assume it's likely something wrong with the nested routes.
I've tried altering the order of my routes and have put console log statements in the controller I anticipated hitting once the link-to statement was hit - so far I haven't entered the controller.
app/router.js
import EmberRouter from '#ember/routing/router';
import config from './config/environment';
const Router = EmberRouter.extend({
location: config.locationType,
rootURL: config.rootURL
});
Router.map(function() {
this.route('about');
this.route('contact');
this.route('posts', function() {
this.route('post');
this.route('show', { path: '/:post_id' });
this.route('edit', { path: '/:post_id/edit' });
this.route('destroy', {path: ':post_id/destroy'});
});
});
export default Router;
apps/routes/posts/edit.js
import Route from '#ember/routing/route';
export default Route.extend({
model(params) {
console.log('hit this when edit route is hit')
return this.store.findRecord('post', params.post_id);
}
});
app/templates/post/show.hbs
<div class="jumbo show-posts">
...
</div>
{{log this.model.id}}
<div class="col-sm-offset-2 col-sm-10">
<h3>{{#link-to "post.edit" post class=this.model.id}}Update post{{/link-to}}</h3>
</div>
{{outlet}}
...

You have mentioned a wrong route name. It should be posts.edit according to your router.js. You should pass at least one params to the post.edit route.
Have a look at my working ember-twiddle
Since you have mentioned this.route('edit', { path: '/:post_id/edit' }), the route will be expecting at least one of its parameters :post_id is present.
Modify you {{link-to}} as below,
{{#link-to "posts.edit" this.model.id}}Update post{{/link-to}}
You can access the post id in your controller through params.post_id,
model(params) {
console.log('hit this when edit route is hit')
return this.store.findRecord('post', params.post_id);
}

Related

How can Vue router get current route path of lazy-loaded modules on page load?

I have a vue app with router set up like:
import index from './components/index.vue';
import http404 from './components/http404.vue';
// module lazy-loading
const panda= () => import(/* webpackChunkName: "group-panda" */ "./components/panda/panda.vue");
// ...
export const appRoute = [
{
path: "",
name: "root",
redirect: '/index'
},
{
path: "/index",
name: "index",
component: index
},
{
path: "/panda",
name: "panda",
component: panda
},
//...
{
path: "**",
name: "http404",
component: http404
}
];
So the panda module is lazy-loaded. However, when I navigate to panda page, a console.log() of this.$route.path in App.vue's mounted() lifecycle only outputs
"/"
instead of
"/panda"
But index page works well, it shows exactly
"/index"
as expected.
So how can Vue router get current path correctly of a lazy-loaded page, when page is initially loaded? Did I miss something?
Edit:
It can, however, catch the correct path after Webpack hot-reloads. It catches "/" on first visit of panda, but after I change something in source code, webpack-dev-server hot-reloads, then it gets "/panda".
So I guess it has something to do with Vue life-cycle.
There is a currentRoute property that worked for me:
this.$router.currentRoute
May be you need to use $route not $router
check here : https://jsfiddle.net/nikleshraut/chyLjpv0/19/
You can also do it by $router this way
https://jsfiddle.net/nikleshraut/chyLjpv0/20/
Use this.$route.path.
Simple and effective.
Hide Header in some components using the current route path.
get current route path using this.$route.path
<navigation v-if="showNavigation"></navigation>
data() {
this.$route.path === '/' ? this.showNavigation = false : this.showNavigation = true
}
If You have similar problem the correct answer is to use router.onReady and then calling your logic concerning path. Below the official Vue router docs:
router.onReady
Signature:
router.onReady(callback, [errorCallback])
This method queues a callback to be called when the router has completed the initial navigation, which means it has resolved all async enter hooks and async components that are associated with the initial route.
This is useful in server-side rendering to ensure consistent output on both the server and the client.
The second argument errorCallback is only supported in 2.4+. It will be called when the initial route resolution runs into an error (e.g. failed to resolve an async component).
Source: https://v3.router.vuejs.org/api/#router-onready
For vue 3 (Composition API)
It can be as simple as route.path if you define the variable route as: const route = useRoute()
Usage example
If you try the following, each time your route path changes it will console log the current path:
<script setup>
import {useRoute} from 'vue-router'
const route = useRoute()
watchEffect(() => console.log(route.path))
</script>

Angular 2 routes resolve different component

Here is my use case:
When i load url /product/123 i want to load component ProductComponent
This is my setup:
RouterModule.forRoot([
{
path: 'product/:productId',
component: ProductComponent
},
{
path: '**', component: NotFoundComponent
},
]),
Now I have added a resolver to check if that product id exists, so my setup looks like this:
RouterModule.forRoot([
{
path: 'product/:productId',
component: ProductComponent,
resolver: {
productResolver: ProductResolver
}
},
{
path: '**', component: NotFoundComponent
},
]),
My resolver checks if that productId parameter exists via api call. The problem i have is that when productId is not found I want to load NotFoundComponent rather than redirecting to different page (i dont want to change url like angular 2 documentation suggests).
Anyone knows how to do that? if not productId found via resolver load NotFoundComponent without changing url/navigate?
I think all you want to do is skip the location change when you navigate to your NotFoundComponent. I'm assuming you've injected the Router into your resolver and are doing something like this when the ID does not exist:
router.navigate(['someUrl']);
Or you might be using the navigateByUrl method. Either way, you can tell the router not to change the URL:
router.navigate(['someUrl'], {skipLocationChange: true});
Don't see why you'd need to load your component via router settings, I'd put it inside the Component that tries to fetch it from the service, and then if it doesn't get a result back toggle some boolean that controls whether the NotFoundComponent gets shown. Some pseudo-ish code below:
ngOnInit(){
if (this.route.snapshot.params && this.route.snapshot.params['id']){
myService.getTheThingById((success)=>{
this.isFound = true;
},(err)=> {
this.isFound = false;
});
}
Then assuming your NotFoundComponent has a selector in it like 'not-found-component' throw it in the template for the component that's calling the service.
<not-found-component *ngIf='!isFound'></not-found-component>
I once faced this problem.
What I did was, in the component, to create 2 other components (in your case, you have ProductComponent, NotFoundComponent, and the other one you want to navigate to, let's say ArticleComponent)
Then I inserted 2 of the components in the main one :
product.component.html
<app-notFound></app-notFound>
<app-article></app-article>
After that, in your ngOnInit, you see if the parameter is there. If he is, then you log it in a property, let's say isParam = true.
Your template becomes
<app-notFound *ngIf="!isParam"></app-notFound>
<app-article *ngIf="isParam"></app-article>
It may not be the best solution out there, but it worked for me !

VueJS with vue-router how to redirect to a server route

I am trying to redirect a user clicking logout link to the server rendered logout page. But as it stands with code below I just get redirected to the default path.
I have a server route set-up in flask as the following:
#app.route('/logout')
def logout():
logout_user()
return render_template('login.html')
In vue I want to redirect the route so that I am directed to the server route.
<template>
<a v-on:click="logout">Logout</a>
</template>
<script>
export default {
name: SomePage.vue
},
methods: {
logout () {
this.$router.replace('/logout')
// I also tried .go('/logout')
}
}
</script>
Then do I need to set up a route in my router?
export default new Router {
routes: {
{
path: '/'
component: Default
children: [
{
path: '/logout'
// no component added here - is it needed?
}
]
}
}
As I have already redirected to /logout, I am not sure how adding a component for this route would help as I just want to go to the base /logout and get the .html page returned by the server. Any ideas?
I have some problem and find solution ...
try this in vuejs 2 +
this.$router.push('/logout')
Manipulating the window location via $router methods doesn't cause the browser to perform a full page reload, which is what you want in this case. You'll need to set the window location manually:
window.location.replace('/logout')

Ember error on refresh or direct URL

I was unable to find any current answers for this question.
I am building my latest project in Ember and while I am able to access the different routes directly and with refreshes locally, as soon as I build for production and host the site, this no longer works. I believe the slug portions of my routers are correct so not sure what I need to update.
Note: I am using Ember CLI.
Router.js
const Router = Ember.Router.extend({
location: config.locationType
});
Router.map(function() {
this.route('reviews', function() {
this.route('index', {path: '/'});
this.route('review', {path: '/:review_id'});
});
this.route('movies');
this.route('about');
this.route("error", { path: "*path"});
});
Review Model
export default Ember.Route.extend({
model(params) {
const id = parseInt(params.review_id);
const movies = this.get('movies');
return movies.getMovieById(id);
},
movies: Ember.inject.service()
});
If I try to directly access or refresh /about, /reviews, /movies, or /reviews/:review_id I am given a 404. Even though the about route doesn't have a model to retrieve any data. It's simply loading a template. The only route I can refresh on is the very index page of the site.
I found this link here which instructed how to update your htaccess file to redirect requests to Ember's index file. This looks to have solved my problem:
http://discuss.emberjs.com/t/apache-rewrite-rule-for-html5-browser-history-url-bookmarkability/1013

EmberJS: Change path to access a route

I have a Router.map defined to my application. I'm working with EmberJS AppKit architecture. https://github.com/stefanpenner/ember-app-kit
I'd like to access to my page "profile" using the following path:
http://localhost:8000/#/profile
But, the name of my route differ to this path, because it's call user-profile, so I did this:
router.js
var Router = Ember.Router.extend();
Router.map(function () {
this.resource('user-profile', { path: 'profile'}, function() {
//Some other things...
});
});
export default Router;
user-profile.js
export default Ember.Route.extend({
model: function () {
return this.store.find('user-profile');
}
});
When I launch my application, Ember is telling me that profile route doesn't exist, even though I defined the path:
Uncaught Error: Assertion Failed: Error: Assertion Failed: The URL '/profile' did not match any routes in your application
Do you know what's wrong with my code at this point?
Thanks
I dont use ember appkit but perhaps try with underscore, ie 'user_profile' and rename your file too. Just a shot in the dark.
I would have to guess it is the way that you are designing your router and the namespace.
Typically a barebones Ember app requires:
window.App = Ember.Application.create({
LOG_TRANSITIONS: true,
LOG_TRANSITIONS_INTERNAL: true
});
App.Router.map(function () {
this.resource('user-profile', { path: 'profile'}, function() {
//Some other things...
});
In your example your router is not in the App namespace, or whatever your root object is named (It doesn't have to be 'App'). I would give this a try or maybe post more code if there are other factors I do not see here.
Also, typically you would name your route userProfile. While i dont think the dasherized name is a problem, it doesn't follow Ember naming conventions.
Hope this helps.

Categories

Resources