Using Meteor, is it possible to have "dynamic routes?" - meteor

sorry, I'm new to webdev and Meteor and I'm not quite sure of the correct terminology. I am using Meteor-Router to create routes in my Meteor app.
I'm trying to create a test restaurant app, so an entry in my database might be:
name: "Kentucky Fried Chicken"
type: "Fast Food"
On the main page of the app, you see a list of restaurants. But the user can click on any item on that list to get to a more detailed page.
I would rather that the urls don't look like:
/restaurant/123
but more so like:
/fast-food/kentucky-fried-chicken
/japanese/sushi-r-us
/italian/some-italian-restaurant-name
Is this possible to do with Meteor & Meteor-Router? Thank you!
Btw, right now my routes are very simple:
Meteor.Router.add({
'/': 'home',
'/admin': 'admin',
'/403': 'unauthorized'
});

You can use more complex routes than the one you're using now, like this:
Meteor.Router.add({
'/:type/:restaurant': function(type, restaurantName) {
var restaurant = Retaurants.findOne({type: type, name: restaurantName});
Session.set('restaurantFromUrl', restaurant);
// Now your restaurant is in the "restaurantFromUrl" Session
return 'restaurantPage';
}
});
The /:type and /:restaurant will be passed into the callback and be whatever you set them to in your URL. Oh, and you might want to add a /show-restaurant/type/name/ also, else all urls (that aren't set up in other routes) that match the patter "/whatever/url" will try to get a restaurant.
Everything you need to know is here: https://github.com/tmeasday/meteor-router
Oh, and this is just an example. Haven't tested it but it should work.

Current route package for Meteor that most people use is: Iron Router

Related

Exclude nextjs api url from sentry events

I have nextjs app with sentry. I want to add new api route, for example api/status, but I want to exclude it from being sent to sentry as it will clutter logs really fast and use my qouta.
I did a small research and it seems that there is an array of urls you can exclude from being tracked. It's called denyUrls. Read more. I have tried to add my url to this array, but it still tracks this url as part of events:
Sentry.init({
...
denyUrls: [
/api\/status/i,
],
...
});
Am I configuring something wrong or this array is not for the purpose of filtering everts.
If so, what's the best way to filter those? Other option I found which I will try next is beforeSend but it feels a bit overkill to simply exclude url. denyUrls feels like much better fit for what I am trying to achieve
I had the same issue and contacted the support for it. I am directly quoting the support here.
The BeforeSend and DenyUrl are options to filter error events, not transactions. For transaction events, please use the tracesSampler function as described on the page: https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/sampling/#setting-a-sampling-function.
Here is an example to drop all transactions that match a certain name:
tracesSampler: samplingContext => {
if(samplingContext.transactionContext.name == "GET /api/health"){
return 0.0 // never send transactions with name GET /api/health
}
return 0.2 // sampling for all other transactions
}
Note that you might need to customise the function above to better match your scenario.
I hope it will help you ;)
Have a nice day.

The API call doesn't append properly in NextJS

Folder structure
-Pages
--Support
---StaffTable.js
await axios.post('api/updateStaffDetails', { data: dataToSubmit });
What I try: I once encountered this issue this is my previous solution, I just add '/' infront of the API call but this time it doesn't work
await axios.post('/api/updateStaffDetails', { data: dataToSubmit });
My thoughts: It seems like nextJS 'glued' the first name of the page into any API call made in that page in this case a nested static route /support/StaffTable the first name is support.
Actual: /localhost/support/updateUser
Expected: /localhost/api/updateUser
Much help or guide or is much much much appreciated . Thank you , have a good day
This should work -
await axios.post('/api/updateStaffDetails', { data: dataToSubmit });
Any file inside the folder pages/api is mapped to /api/* and will be treated as an API endpoint instead of a page. So axois request to '/api/updateStaffDetails' will call the handler(export a function as default) written in pages/api/updateStaffDetails.js

Setting up 'Trigger Email' Firebase Extension

I learned about firebase and cloud functions recently and have been able to develop simple applications with them.
I now want to expand my knowledge and really struggling with Trigger Email Extension.
On a specific event on my firebase, I want to fire an email to the user in a custom format, but I am unable to even activate the extension for now.
Can someone please explain with example please about these fields marked in the picture?
I had this question too, but got it resolved. Here's your answer:
"Email documents collection" is the collection that will be read to trigger the emails. I recommend leaving named "mail" unless you already have a collection named mail.
"Users collection (Optional)" refers to a collection (if any) that you want to use in tandem with a user auth system. I haven't had this specific use case yet, but I imagine once you understand how Trigger Email operates, it should be somewhat self-explanatory.
"Templates collection (Optional)" is helpful for templates in which you can use handlebar.js is automatically input specific information per user. (eg. <p>Hello, {{first_name}}</p> etc.) Similar to the previously mentioned collections, you can name it whatever you want.
How to create a template (I have yet to actually implement this, so take this with a grain of salt):
In your templates collection, you want to name each document with a memorable ID. Firebase gives the example:
{
subject: "#{{username}} is now following you!",
html: "Just writing to let you know that <code>#{{username}}</code> ({{name}}) is now following you.",
attachments: [
{
filename: "{{username}}.jpg",
path: "{{imagePath}}"
}
]
}
...specifying a good ID would be following. As you can see, the documents should be structured just like any other email you would send out.
Here is an example of using the above template in javascript:
firestore()
.collection("mail")
.add({
toUids: ["abc123"], // This relates to the Users Collection
template: {
name: "following", // Specify the template
// Specify the information for the Handlebars
// which can also be pulled from your users (toUids)
// if you have the data stored in a user collection.
// Of course that gets more into the world of a user auth system.
data: {
username: "ada",
name: "Ada Lovelace",
imagePath: "https://path-to-file/image-name.jpg"
},
},
})
I hope this helps. Let me know if you have an issues getting this set up.

Meteor utilities:avatar data

I'd like to use the utilities:avatar package, but I'm having some major reservations.
The docs tell me that I should publish my user data, like this:
Meteor.publish("otherUserData", function() {
var data = Meteor.users.find({
}, {
fields : {
"services.twitter.profile_image_url_https" : true,
"services.facebook.id" : true,
"services.google.picture" : true,
"services.github.username" : true,
"services.instagram.profile_picture" : true
}
});
return data;
});
If I understand Meteor's publish/subscribe mechanism correctly, this would push these fields for the entire user database to every client! Clearly, this is not a sustainable solution. Equally clearly, however, either I am doing something wrong, or I am understanding something wrong.
Also: This unscalable solution works fine in a browser, but no avatar icons are visible when the app is deployed to a mobile device, for some reason.
Any ideas?
Separate the issue of which fields to publish from which users you want to publish data on.
Presumably you want to show avatars for other users that the current user is interacting with. You need to decide what query to use in
Meteor.users.find(query,{fields: {...}});
so that you narrow down the list from all users to just pertinent ones.
In my app I end up using reywood:publish-composite to publish the users that are related to the current user via an intermediate collection.
The unscalability of utilities:avatar seems, as far as I can tell, to be a real issue, and there isn't much to be done about it except to remove utilities:avatar and rewrite the avatar URL-fetching code by hand.
As for the avatars not appearing on mobile devices, the answer was simply that we needed to grant permission to access remote URLs in mobile-config.js, like this:
App.accessRule("http://*");
App.accessRule("https://*");

Previous page location on IronRouter

Is there a way to get the previous page location before going to the next page in IronRouter?
Is there an event I can use to fetch this information?
Thanks in advance.
Since Iron Router uses the usual History API, you can just use the plain JS method:
history.go(-1);
or
history.back();
Edit: or to check the previous path without following it:
document.referrer;
You can achieve the behavior you want by using hooks.
// onStop hook is executed whenever we LEAVE a route
Router.onStop(function(){
// register the previous route location in a session variable
Session.set("previousLocationPath",this.location.path);
});
// onBeforeAction is executed before actually going to a new route
Router.onBeforeAction(function(){
// fetch the previous route
var previousLocationPath=Session.get("previousLocationPath");
// if we're coming from the home route, redirect to contact
// this is silly, just an example
if(previousLocationPath=="/"){
this.redirect("contact");
}
// else continue to the regular route we were heading to
this.next();
});
EDIT : this is using iron:router#1.0.0-pre1
Apologies for bumping an old thread but good to keep these things up to date saimeunt's answer above is now deprecated as this.location.path no longer exists in Iron Router so should resemble something like the below:
Router.onStop(function(){
Session.set("previousLocationPath",this.originalUrl || this.url);
});
Or if you have session JSON installed (see Session JSON)
Router.onStop(function(){
Session.setJSON("previousLocationPath",{originalUrl:this.originalUrl, params:{hash:this.params.hash, query:this.params.query}});
});
Only caveats with thisis that first page will always populate url fields (this.url and this.originalUrl there seems to be no difference between them) with full url (http://...) whilst every subsequent page only logs the relative domain i.e. /home without the root url unsure if this is intended behaviour or not from IR but it is currently a helpful way of determining if this was a first page load or not

Resources