1

Suppose I have a json object:

{record: [{value:"some string"}, {value:["A string", "B string"]}]}

The output I want to get out of that is quite simple: a string if there is a single string, or a concatenated string if there is an array of strings

value: some string
value: A string, B string

But when I write this code:

<span ng-repeat="r in record">value: {{r.value}}<br/></span>

Both values are considered to be strings and I get this output:

value: some string
value: ["A string", "B string"]

when I write this code:

<span ng-repeat="r in record">value: {{r.value.join(", ")}}<br/></span>

Both values are considered to be arrays and since first one is not, I get this (first value is missing):

value:
value: A string, B string

What would be the best way to handle this?

3 Answers 3

1

You could switch on the type in your expression:

<span ng-repeat="r in record">
    value: {{ Array.isArray(r.value) ? r.value.join(", ") : r.value }}<br/>
</span>

Or you could add a filter to encapsulate the logic:

myModule.filter('joinIfArray', function () {
    return function (input) {
        return Array.isArray(input) ? input.join(", ") : input;
    };
});    

And use it like:

<span ng-repeat="r in record">value: {{ r.value | joinIfArray }}<br/></span>
Sign up to request clarification or add additional context in comments.

1 Comment

I think you want Array.isArray(r.value) instead.
1

Slightly shorter:

<span ng-repeat="r in record">value: {{r.value.join(", ") || r.value}}<br/></span>

3 Comments

That'll throw if r.value's a String.
It does work too, just tried this one, no error was thrown
You're both right. It throws an exception, which causes the second value to be returned. If you wrap in a try catch it would break. This may be fragile. Another approach might be more robust.
1

Another way, it should be recursive.

your current file:

<span ng-repeat="r in record track by $index" ng-include="'mytemplate.html'"></span>

template.html:

<span ng-if="! isArray(r.value)">value: {{r.value}}<br/></span>
<span ng-if="isArray(r.value)"><span ng-include="'mytemplate.html'"></span><span ng-if="!$last">, </span></span>

In the controller:

$scope.is_array = function(data) {
  return Array.isArray(data);
}

4 Comments

For some reason Array.isArray() in template html does not work and in this example I get output as if there is a string in both cases. The filter example works fine, it has Array.isArray() working just fine in js module file. I wonder why Array.isArray() does not work properly in template html?
@yggdraa: oops in fact you need to declare a method in the scope and call it. I modified
oh, I did not notice there was isArray(r.value), used Array.isArray(r.value). Now this method works too. I do like the one with a filter more, though 8)
@yggdraa: i edited, it was Array.isArray before. Yes the filter is the best solution if you dont need recursion. With that kind of structure, you are able to handle lots of recursion cases.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.