Skip to content

Nested Promise support for scope object #533

Closed
@Prinzhorn

Description

@Prinzhorn

From what I can tell #276 has been solved and just hasn't been closed yet (correct?). However, I would like to use arbitrary nested Promises. I think these test cases demonstrate it better than I could with words

import { Liquid } from 'liquidjs';

(async () => {
  const templateEngine = new Liquid();

  const context = {
    a: 1,
    b: Promise.resolve(1),
    async c() {
      return 1;
    },
    d: {
      d: 1,
    },
    e: {
      e: Promise.resolve(1),
    },
    f: {
      async f() {
        return 1;
      },
    },
    g: Promise.resolve({
      g: 1,
    }),
    async h() {
      return {
        h: 1,
      };
    },
    i: Promise.resolve({
      i: Promise.resolve(1),
    }),
    j: Promise.resolve({
      async j() {
        return 1;
      },
    }),
  };

  console.log(await templateEngine.evalValue('a == 1', context), true);
  console.log(await templateEngine.evalValue('b == 1', context), true);
  console.log(await templateEngine.evalValue('c == 1', context), true);
  console.log(await templateEngine.evalValue('d.d == 1', context), true);
  console.log(await templateEngine.evalValue('e.e == 1', context), true);
  console.log(await templateEngine.evalValue('f.f == 1', context), true);
  console.log(await templateEngine.evalValue('g.g == 1', context), true);
  console.log(await templateEngine.evalValue('h.h == 1', context), true);
  console.log(await templateEngine.evalValue('i.i == 1', context), true);
  console.log(await templateEngine.evalValue('j.j == 1', context), true);
  console.log(await templateEngine.parseAndRender('{{a}}', context), '1');
  console.log(await templateEngine.parseAndRender('{{b}}', context), '1');
  console.log(await templateEngine.parseAndRender('{{c}}', context), '1');
  console.log(await templateEngine.parseAndRender('{{d.d}}', context), '1');
  console.log(await templateEngine.parseAndRender('{{e.e}}', context), '1');
  console.log(await templateEngine.parseAndRender('{{f.f}}', context), '1');
  console.log(await templateEngine.parseAndRender('{{g.g}}', context), '1');
  console.log(await templateEngine.parseAndRender('{{h.h}}', context), '1');
  console.log(await templateEngine.parseAndRender('{{i.i}}', context), '1');
  console.log(await templateEngine.parseAndRender('{{j.j}}', context), '1');
})();

Once Liquid has seen a promise or a property that was a promise, it won't resolve promises of properties that follow after that. I hope this is an easy fix and it just takes a wrong branch.

I need this because I'm using Liquid in an Electron app for data processing. And the context I pass in is lazy, because nobody will need all the details (including large buffers) for every template. So I only want to load the data that is needed for the current processing pipeline.

Activity

changed the title [-]Nested Promise support[/-] [+]Nested Promise support for scope object[/+] on Aug 27, 2022
harttle

harttle commented on Aug 27, 2022

@harttle
Owner

This is a very similiar issue with #276. Thanks to almousa1990 we solved a part of the problem: promise for Liquid drops.

After #285 is merged, it seems that I forgot this issue for a long time. Thank you for providing a thorough test case list, and share your use case for this feature. One main concern is performance, but it seems OK in my local branch:

Local:  dist/liquid.node.cjs.js
Latest: dist/liquid.node.cjs.9.41.0.js
Local: 5855.541 ops/s (58435 cycles)
Latest: 5868.726 ops/s (58394 cycles)
Diff: -0.225%

Since old APIs like evalToken and Context.get still work fine (test cases not broken), I'm releasing this feature in a minor version.

Prinzhorn

Prinzhorn commented on Aug 29, 2022

@Prinzhorn
Author

From what I can tell this does everything I ever wanted. So thank you very much! I'll let you know once I actually start implementing most of this on my end and share a link to the product if you're interested.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @Prinzhorn@harttle

        Issue actions

          Nested Promise support for scope object · Issue #533 · harttle/liquidjs