Skip to content
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

Modify object #313

Closed
ArmorDarks opened this issue Nov 1, 2014 · 10 comments
Closed

Modify object #313

ArmorDarks opened this issue Nov 1, 2014 · 10 comments

Comments

@ArmorDarks
Copy link

Hello

Let's imagine we're having an object:

{% set object = {
    title: 'title',
    content: 'content'
} %}

Is there any way to modify it's properties without overriding whole object?

For example, like:

{% set object.title = 'New title' %}

or to add another key:

{% set object.test = 'New key value' %}

Currently such attempts will return error TypeError: Cannot call method 'charAt' of undefined, of course.

Now I wonder, is there any workaroud for it, or it isn't possible and won't be ever possible too?

If I do understand it right, jinja has such possibility, with do block
http://stackoverflow.com/questions/11047886/modifying-dictionary-attributes-in-jinja2

@garygreen
Copy link
Contributor

Duplicate of #307. I don't think nunjucks will support this.

@ArmorDarks
Copy link
Author

Thanks for refing. I've missed that issue.

Jinja has do block for such purposes, which probably was missed by carljm while replying and closing issue.

Considering it, maybe this issue should be closed and 307 reopened with new information?

@carljm
Copy link
Contributor

carljm commented Nov 3, 2014

I don't think this is really a duplicate of #307, since that was specifically about {% set %} not handling attribute updates (which it doesn't in Jinja either). The {% do %} block is a much broader feature (though object modification is one thing that it's good for). Even in Jinja, {% do %} is provided only in an optional extension. I think an implementation of {% do %} for nunjucks would be just fine, but it should probably live externally.

@ArmorDarks
Copy link
Author

Hi carljm. Thanks for reply.

So, in such case this issue should be reopened as enhancement?

@carljm
Copy link
Contributor

carljm commented Nov 3, 2014

@ArmorDarks Well, only if an implementation of {% do %} was desired for nunjucks core. My suggestion is that it should be implemented as an external extension instead, meaning this should stay closed.

@ArmorDarks
Copy link
Author

Sorry for resurrecting quite old issue. I just hope that following information might be useful for beginners, who stuck with same problem.

Solution is quite simple — to write few custom filters, they will work like a charm for modifying of arrays or objects.

Few very basic examples for arrays modifications (CoffeeScript):

# Replace last value of array with `value`
# @example {% set modifiedArray = myArray|popIn('myValue') %}
env.addFilter 'popIn', (array, value) ->
  array.pop()
  array.push(value)
  array

# Add `value` to the end of array
# @example {% set modifiedArray = myArray|pushIn('myValue') %}
env.addFilter 'pushIn', (array, value) ->
  array.push(value)
  array

With same approach you can write filters for setting objects properties too.

Unfortunately, there is no other way around until someone will implement do extension.

@jan-dolejsi
Copy link

jan-dolejsi commented May 12, 2018

This looks simpler and sufficient for this case:

env.addFilter('setAttribute', function(dictionary, key, value) {
            dictionary[key] = value;
            return dictionary;
        });

Usage

{% set myDict = {"key1": 0, "key2": 0, "key3": 0}%}
{% set myDict = myDict|setAttribute('key2', 123) %}
{{myDict['key2']}}

... prints "123" as expected.

@ArmorDarks
Copy link
Author

@jan-dolejsi the output is correct. You've set key2 to 123, and it prints 123 afterward. What did you expect?

@efiand
Copy link

efiand commented Mar 13, 2019

This looks simpler and sufficient for this case:

env.addFilter('setAttribute', function(dictionary, key, value) {
            dictionary[key] = value;
            return dictionary;
        });

Usage

{% set myDict = {"key1": 0, "key2": 0, "key3": 0}%}
{% set myDict = myDict|setAttribute('key2', 123) %}
{{myDict['key2']}}

... prints "123" as expected.

Thank you! I had the same problem, this filter solves it!

@dinhanhthi
Copy link

This looks simpler and sufficient for this case:

env.addFilter('setAttribute', function(dictionary, key, value) {
            dictionary[key] = value;
            return dictionary;
        });

Usage

{% set myDict = {"key1": 0, "key2": 0, "key3": 0}%}
{% set myDict = myDict|setAttribute('key2', 123) %}
{{myDict['key2']}}

... prints "123" as expected.

Works like a charm!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants