Meteor and Iron Router: raise 404 when id doesn't exist
Asked Answered
C

4

7

I'm using Iron Router for my urls and I have this route:

this.route('regionEdit', {
  path: '/region/:_id',
  waitOn: function() {
    return Meteor.subscribe('region', this.params._id);
  },
  data: function() {
    return Regions.findOne({
      _id: this.params._id
    });
  }
});

This works fine when I use this path http://example.com/region/xgok3Etc5mfhtmD7j

Where xgok3Etc5mfhtmD7j is the _id of region. However, when I access to http://example.com/region/whatever, the page renders normally, but without data.

How can I raise a 404 error for this?

Consolata answered 16/5, 2014 at 22:52 Comment(2)
This is talked about in iron-router issue #237. It's possible to return a 404 response from the server but not from the client.Perez
Possible duplicate of How to return 404 using Iron RouterWhiny
S
8

not a 404, but you can render a not found page by doing something like this.

this.route('regionEdit', {
  path: '/region/:_id',
  waitOn: function() {
    return Meteor.subscribe('region', this.params._id);
  },
  data: function() {
    var region = Regions.findOne({
      _id: this.params._id
    });
    if(!region)
      this.render("notFound");
    else
      return region;
  }
});
Sixfold answered 17/5, 2014 at 3:7 Comment(0)
B
5

I think you can try Plugins

According to this documentation there is already a built in plugin for this issue

Router.plugin('dataNotFound', {notFoundTemplate: 'notFound'});

And it is described as

This out-of-box plugin will automatically render the template named "notFound" if the route's data is falsey

Bridgeman answered 2/12, 2014 at 17:31 Comment(4)
I believe that this dataNotFound plugin has to do with template data, not with a missing route or template.Toupee
But @Braulio indicates the template is rendered correctly without data (which means data function returns false) if I am not missing anything. Anyway, I had the same case if I understand correctly and it worked for me.Guacin
You might be right. I'm not sure about the dataNotFound plugin, but I got it to work as a config parameter: Router.configure({notFoundTemplate: '404'});Toupee
The Router.configure({notFoundTemplate: '404'}); template will only be rendered if a corresponding Route is not found. Since OP is using params, the route will be found, so will render, but with no data.Mudra
P
0

In router.js

Router.configure({
    layoutTemplate:'layout',
    notFoundTemplate: 'notFound'
});

Configure your router this way to solve the issue

and Template Part

<template name="notFound">
    <div class="container">

            <h1 class="colorWhite">Oopss..ss..ss..</h1>
            <p class="colorWhite">You are out of the world, let's go back</p>

    </div>
</template>

make it like this.. it should work, in fact, it works for me..

Padegs answered 13/12, 2014 at 23:38 Comment(0)
M
-1

I include a catch all route on my Router.map:

router.js

Router.map(function() {

    ... // other routes

    this.route('404', {
       path: '/*',
       layoutTemplate: 'application', // this actually lives in Router.configure();
       template: 'pageNotFound',
       onBeforeAction: function(){
          console.log('not found');
       }
    });
});

templates.html

<template name="pageNotFound">
    <div>
        <h2>404 - page not found</h2>
    </div>
</template>

<template name="application">
    <div>
        <h1>My Application</h1>

        {{> yield}}

    </div>
</template>

This pageNotFound template then gets rendered in the {{> yeild}} partial of the application template if none of the other routes pick up the uri path.

Moreen answered 23/8, 2014 at 17:23 Comment(1)
Ok. Any more details you can perhaps offer?Moreen

© 2022 - 2024 — McMap. All rights reserved.