Customize routerLink in Angular 5 - angular5

In my application I am using routerLink to create my link as per according to parameter passed in routerLink.
<a [routerLink]="['/home/global/userprofile',UserId]">
Above code generate links with the userId provided, but I want to customize angular routerLink so that I can check if UserId is valid or not, if valid I will return the converted href link throught this and if not I will return blank or null url.
I can not use any other directive approach or pipe factories as I am using this routerLink code in several places in my project so I just not want to go and change each and every where that code is writtern. Can anyone guide me in this? I just need concept, I can write code for the idea.
If required, I can explain it more if any queries for this.

Instead of using routerLink directive, I suggest You to use a programmatical redirection in your component class, like this:
HTML component file
<a (click)="goToUserProfile(UserId)">Some link</a>
TS Component class:
import { Router } from '#angular/router';
constructor(private router: Router) {}
goToUserProfile(userId: number) {
if (/* userId verification*/) {
this.router.navigate(['/home/global/userprofile', userId]);
}
// do nothing
}
Otherwise, you can use a router guard, here are some useful links:
Angular Routing and navigation
Using Route Guards
Hope it helps.

Related

Vue/Nuxt: How to make a component be truly dynamic?

In order to use a dynamically-defined single page component, we use the component tag, thusly:
<component v-bind:is="componentName" :prop="someProperty"/>
...
import DynamicComponent from '#/components/DynamicComponent.vue';
...
components: {
DynamicComponent
},
props: {
componentName: String,
someProperty: null,
}
The problem is, this isn't really very dynamic at all, since every component we could ever possibly want to use here needs to be not only imported statically, but also registered in components.
We tried doing this, in order at least to avoid the need to import everything:
created() {
import(`#/components/${this.componentName}.vue`);
},
but of course this fails, as it seems that DynamicComponent must be defined before reaching created().
How can we use a component that is truly dynamic, i.e. imported and registered at runtime, given only its name?
From the documentation: Emphasis mine
<!-- Component changes when currentTabComponent changes -->
<component v-bind:is="currentTabComponent"></component>
In the example above, currentTabComponent can contain either:
the name of a registered component,
or a component’s options object
If currentTabComponent is a data property of your component you can simply import the component definition and directly pass it to the component tag without having to define it on the current template.
Here is an example where the component content will change if you click on the Vue logo.
Like this:
<component :is="dynamic" />
...
setComponentName() {
this.dynamic = () => import(`#/components/${this.componentName}.vue`);
},
Solution for Nuxt only
As of now its possible to auto-import components in Nuxt (nuxt/components). If you do so, you have a bunch of components ready to be registered whenever you use them in your vue template e.g.:
<MyComponent some-property="some-value" />
If you want to have truly dynamic components combined with nuxt/components you can make use of the way Nuxt prepares the components automagically. I created a package which enables dynamic components for auto-imported components (you can check it out here: #blokwise/dynamic).
Long story short: with the package you are able to dynamically import your components like this:
<NuxtDynamic :name="componentName" some-property="some-value" />
Where componentName might be 'MyComponent'. The name can either be statically stored in a variable or even be dynamically created through some API call to your backend / CMS.
If you are interested in how the underlying magic works you can checkout this article: Crank up auto import for dynamic Nuxt.js components
According to the official Documentation: Starting from v2.13, Nuxt can auto import your components when used in your templates, to activate this feature, set components: true in your configuration
you are talking about async components. You simply need to use the following syntax to return the component definition with a promise.
Vue.component('componentName', function (resolve, reject) {
requestTemplate().then(function (response) {
// Pass the component definition to the resolve callback
resolve({
template: response
})
});
})

Dynamically decide when to use vue router

I have a big web application which I am building with vuejs and laravel.
Along the way, I have to switch between
<router-link></router-link> and <a></a> tags
so I build a template that I have a link on it I want it to automatically detect if vue <router-view></router-view>
is available otherwise just use the normal href tag
The below code is the function I have assigned to the click function but it turns out not to be working
try {
this.$router.push("/cart");
} catch (error) {
window.location.href = "/cart";
}
}
My question is
is there any way I can dynamically detect the presence of vue router and as well decide on which tag to use.
Either
window.location.href
or
this.$router.push()

Vuepress - Add component to each page

The documentation in regards to this is quite short. I want to add a Vue component to each page in the app, without having to manually declare it in each template.
I managed to add a enhanceApp.js file and add this to it:
import MyComponent from './components/my-component'
export default ({
Vue,
options,
router,
siteData
}) => {
Vue.component('MyComponent', MyComponent)
}
The app runs but I don't see the component anywhere. Any tips or other ways I can achieve this? Thanks!
You do not need to put it in enhanceApp.js, just having the component in /.vuepress/components is sufficient.
Although, if you want to keep them outside that folder, that might be the way to get Vuepress to know about them.
Use it in an md file as you would do in a Vue template,
<MyComponent></MyComponent>
This is an old question and might only apply to V1 but this is simple to accomplish.
Add your Vue component to .vuepress/components as usual
In .vuepress/config.js add the following:
module.exports = {
// rest of config...
globalUIComponents: [
'YourComponent'
]
}
Don't even need to import your component.
See docs for more info.

Vue router not navigating

I'm having problems getting VueRouter to navigate.
Within my app some pages work fine, and with identical code, other pages the routing doesn't work / page doesn't update navigate.
Are there some gotchas with the router? Like you cannot call the router from within components or... ?
named route in my app
export default new VueRouter({
routes: [
{
path: '/grams/one/:cname',
component: GramsOne,
name: "gramsOne"
},
...
Then inside a component on a page:
<q-btn v-for='(rel, key) in gram.relatedItems' :key='key'
color='secondary'
#click="goGram(rel)"
>
{{rel.cn}}
</q-btn>
// later in the script:
methods: {
goGram(gram) {
let newRoute = {
name: 'gramsOne',
params: {cname: gram.cname}
}
console.log('goGram', newRoute)
this.$router.push(newRoute)
}
},
Elsewhere on the same page, simple routes work.
The URL address will get updated in the browser.
I see the right console log with route info
But the page/content will not change.
Once the URL bar has been updated, I can hit ctrl-R and the new page will get loaded. So the destination route is working fine.
From other pages in the same app I can use the same route to target new destination and loads fine.
This is also loading with the same URL and just a query param different that is causing the problem.
/app/items/foo
/app/items/bar
where bar is a type of some property /app/items/:foo
I have tried various combinations of named routes, routes using etc, and can't really see a pattern.
"vue": "~2.5.0",
"vue-resource": "^1.3.4",
"vue-router": "^2.7.0"
Thanks any hints!
The Component in this case is the same, so vue will reuse the instance.
The this.$route in the component will change but created(), beforeMounted() and mounted() hooks won't be callled.
Which is probably where you use the this.$route.params.cname
To force vue to create a new component instance you can set a unique key on the like <router-view :key="$route.fullPath">
Another options is to react to changes in the $route with a watcher:
watch: {
"$route.params.cname": {
handler(cname) {
// do stuff
},
immediate: true
}
}
Router can be called within a component just fine. In fact, you usually call router from the component.
From the code snippets provided, at one point in the code you use cn, then at other point you use cname. That might be the problem why it never quite work for you.
I create a codesandbox to recreate your scenario, and besides that minor naming mentioned above, things seem to work just fine.

Router view in Aurelia

I want to create an application in which I want following functionality:
Some links needs to be opened in router-view which is working fine.
But some links i want to open in current window(means full page). But if I click on page having routerview, then it starts opening url in that routerview only.
How can we stop this?
I believe you're looking for a way to set the root component. Like this:
import { Aurelia } from 'aurelia-framework';
export class MyCustomElement {
static inject = [Aurelia];
constructor(aurelia) {
this.aurelia = aurelia;
}
//call this method by using click.delegate in a button
goToAnotherPlace() {
this.aurelia.setRoot('./your-full-page-component');
}
}
By doing this, you're changing the whole page (everything inside aurelia-app attribute). You might have to configure another router.