Giter Site home page Giter Site logo

Comments (13)

delgermurun avatar delgermurun commented on June 30, 2024 1

Hello @michalvalasek,

It's not really router's issue. You can check subsReady() on your template helper. If it's ready server sent data.

So you can check whether article exist or not on client. a = Articles.findOne({slug: slug}) if (a) ... smth like than. if a is undefined, you can show another template or redirect to not-found page.

PS: I hope you understand me. But if you don't feel free to ask further. I can show you code example. I can't explain well, cause my English isn't good enough :).

from flow-router.

vladshcherbin avatar vladshcherbin commented on June 30, 2024

@delgermurun okay, the idea is how to handle 404. For example, we have route

FlowRouter.route('/services/:slug', {
    name: 'service',
    subscriptions: function (params) {
        this.register('service', Meteor.subscribe('service.visible', params.slug));
    },
    action: function (params) {
        if (FlowRouter.subsReady()) {
            // check for a db document
            // If no document
            // Redirect to 404
            // else show it!
            var service = Services.findOne({slug: params.slug});
            if (!service) {
                FlowLayout.render('404');
            } else {
                FlowLayout.render('mainLayout', {main: "service"});
            }
        } else {
            FlowLayout.render('mainLayout', {main: "loading"});
        }
    }
});

in db we have service with slug laptop-repairs.

  • While the subscription is not ready -> we want to render mainLayout with Loading template
  • When it is ready -> we want to check, if this db document exists.
    • If yes -> render it to mainLayout
    • If no (e.g. we wrote lapttf-fa) -> we want to render 404 page (e.g. without mainLayout)

Since we don't have controllers, you propose to do this in template helpers.
Maybe you can provide a simple example?

from flow-router.

delgermurun avatar delgermurun commented on June 30, 2024

@vladshcherbin It doesn't work because action doesn't work reactively. Although if it works, it's doing too much thing. IMHO, route should be simple.

FlowRouter.route('/services/:slug', {
    name: 'service',
    subscriptions: function (params) {
        this.register('service', Meteor.subscribe('service.visible', params.slug));
    },
    action: function (params) {
       FlowLayout.render('mainLayout', {main: "service"});
    }
});
Template.service.onCreated({
  this.autorun(function() {
    if (FlowRouter.subsReady()) {
      var service = Services.findOne({slug: params.slug});
      if (!service) {
         FlowRouter.go('/404');
      }
    }
  });
})

Basically, here is how I do.

from flow-router.

vladshcherbin avatar vladshcherbin commented on June 30, 2024

@delgermurun yep, my example does not work, this is just my thoughts on how it may be done if it was reactive

thanks for an example, being an MVC guy it is kinda strange to do this stuff in the View layer. maybe in some before hook, but again subscriptions... anyway, thanks for a workaround.

also, if you go to any page (/bla-bla) -> it will render the 404, but the url will be still bla-bla.
In this workaround, it will redirect to 404 and change url. kinda ugly.
Sure, we can redirect all not found pages to 404, but I don't want to change the url.

Any thoughts on another workaround ?

from flow-router.

delgermurun avatar delgermurun commented on June 30, 2024

@vladshcherbin I'm MVC (django) guy too. But we have to think differently :).

If you don't want to redirect.

Templates.service.helpers({
  isReady: function() {
    return FlowRouter.subsReady();
  },
  service: function() {
    return Services.findOne({slug: params.slug});
  }
});
<template name="service">
{{#if isReady }}
  {{#if service}}
    ...service detail..
  {{else}}
    {{> notFound}}
  {{/if}}
{{else}}
  {{> loading}}
{{/if}}
</template>

here is basic logic. You can improve it many ways (I guess). For example: you can create reactive service var in template's onCreated hook. So query doesn't run multiple.

Checking isReady, before checking existence is important.

from flow-router.

vladshcherbin avatar vladshcherbin commented on June 30, 2024

@delgermurun yep, this is totally different. And this is the workaround I would probably use, but..

for example the mainLayout is:

<template name="mainLayout">
    <header>
        {{> nav}}
    </header>
    <main>
        {{> Template.dynamic template=main}}
    </main>
    <footer>
        {{> footer}}
    </footer>
</template>

What if I don't want to render nav, footer on 404.. Probably, I can make more dynamic areas and pass data there in every route, but it kinda sucks.

I feel like a pain in the a., but this are all life cases, all of them I'm facing right now, sorry guys.

Maybe @arunoda can share his thoughts on that?

from flow-router.

delgermurun avatar delgermurun commented on June 30, 2024

@vladshcherbin how about render different layout onCreated

Template.service.onCreated({
  this.autorun(function() {
    if (FlowRouter.subsReady()) {
      var service = Services.findOne({slug: params.slug});
      if (!service) {
         FlowLayout.render('404');
      }
    }
  });
})

maybe it'll work.

from flow-router.

vladshcherbin avatar vladshcherbin commented on June 30, 2024

@delgermurun oh, that is the trick! Didn't think of it.

So, I ended with a helper:

{{#if isReady 'service'}}
    // ...
{{else}}
    {{> spinner}}
{{/if}}

combined with:

Template.service.onCreated(function () {
    this.autorun(function () {
        if (FlowRouter.subsReady()) {
            var service = Services.findOne({slug: FlowRouter.getParam('slug')});

            if (!service) {
                FlowLayout.render('404');
            }
        }
    });
});

@michalvalasek this should help you too

@delgermurun thanks a lot again! πŸ‘

from flow-router.

delgermurun avatar delgermurun commented on June 30, 2024

@vladshcherbin Glad it helped.

from flow-router.

michalvalasek avatar michalvalasek commented on June 30, 2024

@delgermurun @vladshcherbin Thank you guys, this is really helpful to me!

Just a side note: I feel a bit dirty for putting redirects on the template level. I feel like it belongs to the router.

What do you think about something like this?

FlowRouter.route('/service/:slug', {
  subscriptions: function(params) {
    this.register('service', Meteor.subscribe('serviceBySlug', params.slug));
  },
  action: function() {
    if (!!(Services.find().count())) {
      FlowLayout.render('appLayout', { main: "serviceDetail" });
    }
    else {
      FlowLayout.render('404');
    }
  }
});

from flow-router.

vladshcherbin avatar vladshcherbin commented on June 30, 2024

@michalvalasek yep, it feels very dirty, but we don't have any data control layer, smth like a controller. Maybe it can be done in after hook, but then we need to receive the data from a subscription in that hook.

Anyway, middlewares are WIP, maybe this will be implemented.

from flow-router.

michalvalasek avatar michalvalasek commented on June 30, 2024

Yep, I was thinking about middlewares too, but the problem is the middlewares are being run before the subscriptions section (if iI'm not mistaken).

from flow-router.

arunoda avatar arunoda commented on June 30, 2024

This is a middleware and data handling related issue and related with #80.
So, I'm closing this and let's discuss at #80

from flow-router.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.