Is there different between when(Predicate, Action) and when(Boolean, Action)

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Is there different between when(Predicate, Action) and when(Boolean, Action)

zhangpengpeng
I'm confused with those methods behavior.I have a test like this:

    @Test
    public void testWhenFunction() throws Exception {
        String path = "A";
        EmbeddedApp.fromHandlers(chain -> {
            chain.prefix(path,chain1 -> {
                chain1.when(path.equals("A"), chain2 -> chain2.all(ctx -> ctx.next(Registry.single("hello")))).
                        when(path.equals("B"),chain2 -> chain2.all(ctx -> ctx.next())).
                        insert(chain2 -> chain2.all(ctx-> {
                            System.out.println("call insert? " + ctx.get(String.class));
                            ctx.next();
                        })).get("",ctx -> {
                    ctx.render(ctx.get(String.class));
                });
            });
        }).test(testHttpClient -> {
            assertEquals("hello",testHttpClient.getText(path));
        });
    }

It uses when(Boolean, Action) and can pass.But if I use when(Predicate, Action),there are exception!

can pass (Boolean, Action):

   when(path.equals("A"), chain2 -> chain2.all(ctx -> ctx.next(Registry.single("hello")))).
                        when(path.equals("B"),chain2 -> chain2.all(ctx -> ctx.next()))

exceptionwhen (Predicate, Action):

      when(ctx->path.equals("A"), chain2 -> chain2.all(ctx -> ctx.next(Registry.single("hello")))).
                        when(ctx->path.equals("B"),chain2 -> chain2.all(ctx -> ctx.next()))


Is there something I misunderstand?
Reply | Threaded
Open this post in threaded view
|

Re: Is there different between when(Predicate, Action) and when(Boolean, Action)

Luke Daley
Administrator
when(Predicate, Action) tests for each request.
when(boolean, Action) tests once, during chain construction time.

If your condition is based on the request, you need to use the Predicate variant. If it's based on something that is known when defining the chain, you should use the boolean variant.
Reply | Threaded
Open this post in threaded view
|

Re: Is there different between when(Predicate, Action) and when(Boolean, Action)

zhangpengpeng
Thank you for the reply!

But in my test,if I use Predicate,even though the handler runs,I lost the registered object  in the downstream handlers.

I mean in the test

 chain1.when(ctx->path.equals("A"), chain2 -> chain2.all(ctx -> ctx.next(Registry.single("hello"))))

even the Predicate(ctx->path.equals("A")) return true,I still lost "hello" in the downstream handlers.I just got exception:

   2016-08-23 19:38:44 [ratpack-compute-4-2] ERROR ratpack.error.internal.DefaultDevelopmentErrorHandler - exception thrown for request to /A
ratpack.registry.NotInRegistryException: No object for type 'java.lang.String' in registry

but if I used boolean

   chain1.when(path.equals("A"), chain2 -> chain2.all(ctx -> ctx.next(Registry.single("hello"))))

I can get "hello".

What's the reason they have different behaviors?Thanks for your help!
Reply | Threaded
Open this post in threaded view
|

Re: Is there different between when(Predicate, Action) and when(Boolean, Action)

Luke Daley
Administrator
The reason is that .next(Registry) makes the registry contents available to sibling and child handlers (i.e. handlers attached to the same chain, or a child).

The boolean variant, passes the same chain to the action. The Predicate variant creates a child chain.

If you want to make something visible to all downstream handlers, you should add it to the request registry via `request.add(thing); ctx.next()`.
Reply | Threaded
Open this post in threaded view
|

Re: Is there different between when(Predicate, Action) and when(Boolean, Action)

zhangpengpeng
Thanks!That helps a lot!