Passing query parameter by using navigateByUrl() - javascript

I am trying to Navigate to a new page on click of an icon and below is the code
this.prj = e.data.project_number;
this.router.navigateByUrl('/dashboard/ProjectShipment/634');
Instead of this hardcoded query parameter 000634 I have to pass a this.prj in to it. My path is like below
const appRoutes: Routes = [
{
path: 'dB',
data: { title: 'Dashboard' },
children: [
{
path: 'ProjectShipment/:reportProject',
component: ProjectShipmentComponent,
data: { title: 'Project Shipment' },
}

You can use 'router.navigate' instead 'router.navigateByUrl':
this.router.navigate([URL],{ queryParams: { id: this.prj });

Simply use string interpolation
this.router.navigateByUrl(`/dashboard/ProjectShipment/${this.prj}`);

// Set our navigation extras object
// that passes on our global query params and fragment
let navigationExtras: NavigationExtras = {
queryParams: {...},
state: {...}
};
// Redirect the user
this.router.navigateByUrl(redirect, navigationExtras);
NavigationExtras docs
EDIT: https://stackoverflow.com/a/44865817/5011818 this is also worth to look at

this.router.navigate(['/route1'], { variable1: "Value" });
this.router.navigateByUrl('/route1', { variable1: "Value" });
Please none: if your url is urlencoded use navigateByUrl, if your url is not urlencoded use navigate

Related

Dynamically return config value (node.js)

I'm building a content middleware which gather contents from our external publishers. The publishers will share their contents either in rss or json and the key/value field would be different from each other. To make thing easier, I created a config file where I can pre-defined the key/value and the feed type. The problem is, how can I dynamically return this config value based on publishers name.
Example: To get Publisher #1 feed type, I just can use config.articles.rojak_daily.url_feed
my config file /config/index.js
module.exports = {
batch:100,
mysql: {
database: process.env.database,
host: process.env.host,
username: process.env.username,
password: process.env.password
},
articles:{
rojak_daily:{ // Publisher 1
url: 'xxx',
url_feed: 'rss',
id: null,
Name: 'title',
Description: 'description',
Link: 'link',
DatePublishFrom: 'pubDate',
LandscapeImage: 's3image',
SiteName: 'Rojak Daily',
SiteLogo: null
},
rojak_weekly:{ // publisher 2
url: 'xxx',
url_feed: 'json',
id: null,
Name: 'Name',
Description: 'Desc',
Link: 'link',
DatePublishFrom: 'pubDate',
LandscapeImage: 's3image',
SiteName: 'Rojak Weekly',
SiteLogo: null
}
}
}
my main application script
const config = require('#config'); // export from config file
class Main {
constructor(){
this.publishers = ['rojak_daily','rojak_weekly'];
}
// Main process
async startExport(){
try{
for(let publisher of this.publishers){
const feedType = await this.getFeedType(publisher)
const result = (feedType == 'rss')? await this.rss.start(publisher): await this.json.start(publisher)
return result
}
}catch(err){
console.log("Error occured: ", err)
}
}
// Get feed type from config
async getFeedType(publisher){
return await config.articles.rojak_daily.url_feed;
// this only return publisher 1 url feed.
// my concern is to dynamically passing variable
// into this config file (example: config.articles.<publisher>.url_feed)
}
}
module.exports = Main
async getFeedType(publisher){
return await config.articles[publisher].url_feed;
}
You can access properties of objects by variable
You could either loop over the articles by using Object.entries(articles) or Object.values(articles) in conjunction with Array.prototype.forEach(), or since you already have the name of the publisher you could access that entry with config.articles[publisher].url_feed, like so:
const config = {
articles: {
rojak_daily: { // Publisher 1
url: 'xxx',
url_feed: 'rss',
id: null,
Name: 'title',
Description: 'description',
Link: 'link',
DatePublishFrom: 'pubDate',
LandscapeImage: 's3image',
SiteName: 'Rojak Daily',
SiteLogo: null
},
rojak_weekly: { // publisher 2
url: 'xxx',
url_feed: 'json',
id: null,
Name: 'Name',
Description: 'Desc',
Link: 'link',
DatePublishFrom: 'pubDate',
LandscapeImage: 's3image',
SiteName: 'Rojak Weekly',
SiteLogo: null
}
}
}
const publishers = ['rojak_daily', 'rojak_weekly']
function getFeedType(publisher) {
return config.articles[publisher].url_feed;
}
publishers.forEach(publisher => console.log(getFeedType(publisher)));

router.navigate with query params Angular 5

I'm having an issue with routing to a route with query params I have a function like so
goToLink(link) {
this.router.navigate([`${link.split('?')[0]}`, { queryParams: this.sortParams(link)}]);
}
and this function
sortParams(link) {
let queryParams = url.split('?')[1];
let params = queryParams.split('&');
let pair = null;
let data = {};
params.forEach((d) => {
pair = d.split('=');
data[`${pair[0]}`] = pair[1];
});
return data;
}
okay so basically what Is happening I have a function called goToLink() and that takes in a url and the url that gets passed is a string with query params like so..
https://website.com/page?id=37&username=jimmy
the above is just an example thats not what it actually looks like but its a link string with query parameters now so what happens is I remove the params from the string and store them in a data object in the sortParams() function so when I pass the above string in I get an object that looks like this
{id: 37, username: 'jimmy'}
now thats what i'm passing into the queryParams: section in the router.navigate,
the function should look like this when the object is returned
this.router.navigate([`${link.split('?')[0]}`, { queryParams: {id: 37, username: 'jimmy'}}]);
so i successfully route to the desired route but the query params look like this..
/page;queryParams=%5Bobject%20Object%5D
Am I doing something wrong here??
Any help would be appreciated!
EDIT
If I just change the function to this
this.router.navigate([`${link.split('?')[0]}`, { queryParams: {id: 37, username: 'jimmy'}}]);
I get the same url /page;queryParams=%5Bobject%20Object%5D
Can be of that you had placed the bracket which is supposedly for the 1st param but you had encapsulated it on the whole line of route
Your code:
// This is the end of your route statement: '}}]);' which the close bracket is included
this.router.navigate([`${link.split('?')[0]}`, { queryParams: {id: 37, username: 'jimmy'}}]);
Update route:
place the ] close bracket within the 1st parameter only, try to not place it on the last part of the route statement.
// Update end line: '}});'
this.router.navigate([`${link.split('?')[0]}`], { queryParams: {id: 37, username: 'jimmy'}});
Summary:
this.router.navigate([ url ], { queryParams: { ... } })
If you want to navigate to a URL string including query params, try using router.navigateByUrl.
For example:
this.router.navigateByUrl('/page?id=37&username=jimmy');
Try like this:
this.router.navigate(['my-route', 37], { queryParams: { username: "jimmy"}});
this.router.navigateByUrl('/page?id=37&username=jimmy');
This is better when the params are dynamic.

vue - remove latest child path

so I currently have my router paths set up as such:
{
component: List,
name: "account-list",
path: "list/:id",
// alias: "list/:id/edit_item/:item_id",
children: [
{
path: "edit_item/:item_id",
},
{
path: "*",
redirect: "/account/list/:id"
}
]
}
And let's say we have a url like this: http://localhost:8080/#/account/list/5bb17bdec7fb946609ce8bd4/edit_item/5bbc2d12aded99b39c9eadb9
How would I turn this into:
http://localhost:8080/#/account/list/5bb17bdec7fb946609ce8bd4
I am currently using
this.$router.back()
Which generally works well, but if I were to have accessed another item by directly pasting in its url, this.$router.back() would just revisit the previous url.
So is there a surefire way to guarantee that I would remove the child path?
Vue router will maintain current params when navigating so you should be able to navigate to the named parent route.
For example
this.$router.push({ name: 'account-list' })
The current :id param will be re-used.
If you wanted to make it dynamic, you could work your way up the current route's matched array. For example, to go to the current route's named parent
this.$router.push({
name: this.$route.matched[this.$route.matched.length - 2].name
})
This will only work on nested routes of course as the matched length for top-level routes is only 1.
For non-named routes you must construct the full path with all params interpolated into the string. You could do it by getting the destination routes path property and substituting param tokens with those in this.$route.params but that's going to get messy. Eg
// get parent path property
let path = this.$route.matched[this.$route.matched.length - 2].path
let realPath = path.replace(/:\w+/g, param =>
this.$route.params[param.substr(1)])
this.$router.push(realPath)
This won't work if your paths use advanced pattern matching.
You can move your child route up one level, so that it is not a child anymore. That way the id would show up in the this.$router.params object.
[
{
path: 'list/:id',
component: List,
name: "account-list"
},
{
path: 'list/:id/edit_item/:itemid',
component: Form,
name: "account-form"
}
]
You can do a do a $router.replace to replace the current path.
const id = this.$router.params['id'];
this.$router.replace({
name: 'account-form',
params: { id }
})
Store your list id 5bb17bdec7fb946609ce8bd4 in localStorage and get that localStorage in route script file.And add it your redirect path. For ex:
var listId = localStorage.getItem('listId');
// routh obj
{
component: List,
name: "account-list",
path: "list/:id",
// alias: "list/:id/edit_item/:item_id",
children: [
{
path: "edit_item/:item_id",
},
{
path: "*",
redirect: "/account/list/" + listId
}
]
}
get the list's id first before replacing the route.
let currentId = this.$route.params.id
this.$router.replace({
name: 'list',
params: { id: currentId }
})
also, it would be better if you name your sub routes.

Bind data to component with Vuex

I'm new to vue.js and I'm trying to use vuex. Here is my issue:
I have a list of articles (which is a component) linked with a store with v-for="article in articles and a computed property:
computed: {
articles() {
return this.$store.state.articles
}
}
So here is the data in my store:
state: {
articles: [{
title: "Article 1",
id: 1,
description: "Article 1",
}, {
title: "Article 2",
id: 2,
description: "Article 2",
}
}]
}
When I click on an article, I want it to redirect to the article page template (which is a component) with <router-link :to="{path: '/article/'+article.id}"></router-link>.
What I'm trying to do is bind the data of the correct article in the articlePage template.
The issue is that if I apply the same computed property to my articlePage.vue component with a v-for, I will display all of the article on the same page. I would like to display only the matching id component.
How can I do that?
Thank you for your time :)
From your comments I understand that you use vue-router module
So in your routes.js (or structure ) your must have something like this
const router = new VueRouter({
routes: [
{ path: '/articles', component: articlesPage },
{ path: '/article/:id', component: articlePage }
]
})
Then in your articlePage component you can extract ":id" like this:
this.$route.params.id
because vue-router gives you access to the object $route with methods and properties
Check more here https://router.vuejs.org/guide/essentials/dynamic-matching.html
then you can use it to search the articles array and find the data and present them
e.x.
computed:{
selectedArticle(){
var article_id = this.$route.params.id;
var articles = this.$store.state.articles;
var article = null;
for(var a=0;a<articles.length;a++){
if(articles[a].id == article_id ){
article = articles[a];
break;
}
}
return article;
}
}

When using Joi with Hapi, how does one setup a require on one key but allow any and all other keys?

I'm trying to write a Joi validation for a JSON object coming into a Hapi handler. So far the code looks like this:
server.route({
method: 'POST',
path: '/converge',
handler: function (request, reply) {
consociator.consociate(request.payload)
.then (function (result) {
reply (200, result);
});
},
config: {
validate: {
payload: {
value: Joi.object().required().keys({ knownid: Joi.object() })
}
}
}
});
You can see the Joi object validation so far in the config: validate: code section above. The JSON coming in looks like this.
"key": '06e5140d-fa4e-4758-8d9d-e707bd19880d-testA',
"value": {
"ids_lot_args": {
"this_id": "stuff",
"otherThign": "more data"
},
"peripheral_data": 'Sample peripheral data of any sort'
}
In this JSON above the key and value at the root of the object are required, and the section called ids_lot_args is required. The section that starts with peripheral_data could be there or not, or could be any other JSON payload. It doesn't matter, only key and value at the root level and ids_lot_args inside the value are required.
So far, I'm stumbling through trying to get the Joi validation to work.
Any ideas on how this should be setup? The code repo for Joi is located at https://github.com/hapijs/joi if one wants to check it out. I've been trying the allow all functions on objects to no avail so far.
You just need to call the unknown() function on the value object:
var schema = Joi.object({
key: Joi.string().required(),
value: Joi.object({
ids_lot_args: Joi.object().required()
}).unknown().required()
});
You can use the "allowUnknown" parameter:
validate : {
options : {
allowUnknown: true
},
headers : {
...
},
params : {
...
},
payload : {
...
}
}
}
Try using Joi.any()
server.route({
method: 'POST',
path: '/converge',
handler: function (request, reply) {
consociator.consociate(request.payload)
.then (function (result) {
reply (200, result);
});
},
config: {
validate: {
payload: {
key: Joi.string().required(),
value: Joi.object({
ids_lot_args: Joi.object().required(),
peripheral_data: Joi.any()
})
}
}
}});

Categories