-
Notifications
You must be signed in to change notification settings - Fork 640
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Async filters don't work if render callback is not used #1474
Comments
This is how I do it:
|
@geleto it doesn't work for any real async case, just try to send setTimeout promise with 0 delay to this filter. I expect the following filter will work and render "result":
|
Here are some example tests for real async cases: import { expect } from 'chai';
import * as nunjucks from 'nunjucks';
describe('await filter tests', () => {
let env: nunjucks.Environment;
beforeEach(() => {
env = new nunjucks.Environment();
// Implement 'await' filter for resolving promises in templates
env.addFilter('await', function (promise: Promise<any>, callback: (err: Error | null, result?: any) => void) {
promise.then(result => {
callback(null, result);
}).catch(err => {
callback(err);
});
}, true);
});
it('should handle custom async filter with global async function', (done) => {
// Add global async function
env.addGlobal('fetchUser', async (id: number) => {
// Simulate async operation
await new Promise(resolve => setTimeout(resolve, 10));
return { id, name: `User ${id}` };
});
const template = '{% set user = fetchUser(123) | await %}Hello, {{ user.name }}!';
env.renderString(template, {}, (err, result) => {
if (err) return done(err);
expect(result).to.equal('Hello, User 123!');
done();
});
});
it('should handle asyncEach with array of promises', (done) => {
// Add global function to fetch records
env.addGlobal('getRecords', () => {
// Return an array of promises (each record is a promise)
return [
new Promise(resolve => setTimeout(() => resolve('Record 1'), 10)),
new Promise(resolve => setTimeout(() => resolve('Record 2'), 20)),
new Promise(resolve => setTimeout(() => resolve('Record 3'), 15))
];
});
const template = `{%- set records = getRecords() -%}
{%- asyncEach rec in records -%}
{{ rec | await }}{% if not loop.last %}\n{% endif %}
{%- endeach %}`;;
env.renderString(template, {}, (err, result) => {
if (err) return done(err);
expect((result as string).trim()).to.equal('Record 1\nRecord 2\nRecord 3');
done();
});
});
}); |
@geleto Thank you! It seems that we can't call renderString without callback if we have async filters import { expect } from 'chai';
import * as nunjucks from 'nunjucks';
describe('await filter tests', () => {
let env: nunjucks.Environment;
beforeEach(() => {
env = new nunjucks.Environment();
env.addFilter('fetchUser', async (id: string, callback: (err: Error | null, result?: any) => void) => {
// Simulate async operation
const promise = new Promise(resolve => setTimeout(() => resolve(`User ${id}`), 10));
promise.then(result => {
callback(null, result);
}).catch(err => {
callback(err);
});
}, true);
});
it('should render using renderString without callback', () => {
const template = '{% set user = "User 123" %}Hello, {{ user }}!';
const result = env.renderString(template, {});
expect(result).to.equal('Hello, User 123!');
});
it('should handle custom async filter using renderString with callback', (done) => {
const template = '{% set user = "123" | fetchUser %}Hello, {{ user }}!';
env.renderString(template, {}, (err, result) => {
if (err) return done(err);
expect(result).to.equal('Hello, User 123!');
done();
});
});
// Failed!
it('should handle custom async filter using renderString without callback', () => {
const template = '{% set user = "123" | fetchUser %}Hello, {{ user }}!';
const result = env.renderString(template, {});
expect(result).to.equal('Hello, User 123!');
});
});
await filter tests
✔ should render using renderString without callback
✔ should handle custom async filter using renderString with callback
1) should handle custom async filter using renderString without callback
2 passing (24ms)
1 failing
1) await filter tests
should handle custom async filter using renderString without callback:
AssertionError: expected null to equal 'Hello, User 123!' |
olegsmetanin
changed the title
Async filters doesn't work
Async filters don't work if render callback is not used
Sep 13, 2024
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
"nunjucks": "^3.2.4",
Async filter
with template
doesn't work and renders nothing
The text was updated successfully, but these errors were encountered: