2

I'm new to Angular.JS and trying to figure out how to properly implement ng-repeat.

I have a data object in my scope that was formed from JSON from my database. One of the returned 'fields' can sometimes either be just a single string, or an array.

Example:

Email Address = "[email protected]" or
Email Address = ["[email protected]", "[email protected]", "[email protected]"]

I would simply like to display in a series of spans whatever Email Address would contain. So far, I've done this:

<span ng-repeat="EMAIL_ADDRESS in data.EMAIL_ADDRESS">
    <span>{{EMAIL_ADDRESS}}</span><br />
</span

For the Email Address that's an array of 3, I get this (which I want):

    <span>[email protected]</span><br />
    <span>[email protected]</span><br />
    <span>[email protected]</span><br /> 

For the Email Address that's just a string I get:

    <span>m</span><br />
    <span>e</span><br />
    <span>@</span><br />
    <span>t</span><br />
    <span>e</span><br />
    <span>s</span><br />
    <span>t</span><br />
    <span>.</span><br />
    <span>c</span><br />
    <span>o</span><br />
    <span>m</span><br />

How can I prevent the later situation? I know this is more Javascript behavior, but I'm not sure how to put it in Angular.

4 Answers 4

2

if you can't change the returned object from the database, or if you have do do this on multiple variables, you could implement a function to transform the string into an array, which will prevent your ng-repeat to parse it

One possible function could be implemented directly in your controller :

$scope.formatData=function(objectFromDB){
    if(!angular.isArray(objectFromDB))
       return [objectFromDB];
    else
       return objectFromDB;
    }

Then you just have to call the function with your data

<span ng-repeat="EMAIL_ADDRESS in formatData(data.EMAIL_ADDRESS)">
Sign up to request clarification or add additional context in comments.

1 Comment

Easy to implement, and works like a charm. I feel that this answer was the best giving it's portability and clean approach. Thanks
1

The angular way would be to format your data after you receive it. If the value is a string replace it with an array containing that value. This way your template will receive a consistent result and your controller logic will deal with consistent data structures.

Edit: I would also not bind the raw return data from the server to the $scope directly. I like to add a level of separation between the data names/types of the server and of the client to ensure future ease of change and no strong coupling.

JS:

$http.get('/my/data').success(function(data) {
  //here's where I'd do all the data transformation and binding
  if(angular.isArray(data.EMAIL_ADDRESS)) {
    $scope.emailAddresses = data.EMAIL_ADDRESS;
  else {
    $scope.emailAddresses = [data.EMAIL_ADDRESS];
  }
});

HTML:

<span ng-repeat="emailAddress in emailAddresses">

This way your templates are not bound to the server api return values/properties

Comments

0

You can have separate spans/docs to show different cases: with ngRepeat for arrays and without it for simple string.

So kind of

<div ng-show="isString(data.EMAIL_ADDRESS)">{{data.EMAIL_ADDRESS}}<div><div ng-hide="isString(data.EMAIL_ADDRESS)" ng-repeat="address in data.EMAIL_ADDRESS">{{address}}<div>

Comments

0

When you fetch your data from server:

EMAIL_ADDRESS = EMAIL_ADDRESS instanceof Array ? EMAIL_ADDRESS : [EMAIL_ADDRESS]

Comments

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.