Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

So I'm trying to create a basic angular application that parses some CSV input, and fills a table with the parsed data.

You can see a plunker of what I'm trying to achieve here - http://plnkr.co/edit/6QFT4AcV4KpiSG23EdOS

Basically - as you can see - I have a <textarea> where the user will paste in some CSV, and the table below should then be filled with the data.

<div class="excelArea">
    <textarea name="excelData" ng-model="excelData"></textarea>
</div>

This is the javascript I have so far, but I'm struggling with a few things 1. Seperating the email from the name 2. Pushing the data back into the $scope.inviteList;

app.controller("InviteController", function($scope) {

    //Initliase objects
    $scope.excelData = "";
    $scope.errorMessage = "";
    $scope.inviteList = [];

    $scope.$watch("excelData", function() {

        var lines, lineNumber, data, length;

        lines = $scope.excelData.match(/[^\r\n]+/g);
        lineNumber = 0;

        for (var i = lines.length - 1; i >= 0; i--) {

            l = lines[i];
            lineNumber++;
            data = l.split(/\t/);

            var email = ? ? ?
            var name = ? ? ?

            $scope.inviteList.push({
                name: name,
                email: email,
                status: "not sent"
            });

        };

    });

});

Some basic information:

The CSV will be two columns (name, email) and will look like this:

John Thompson,[email protected]
Robin Peters, [email protected]
Bill Bob, [email protected]
share|improve this question

3 Answers 3

up vote 1 down vote accepted

Many problems in your code :

  • You could juste use split on your input instead of regexes, it makes everything easier
  • Your HTML isn't valid td should be inside tr and not the other way around
  • Your array was never cleared
  • Your bindings inside ng-repeat didn't use variable i defined here : i in inviteList
  • You should avoid unscoped variables (without var keyword) whenever possible

Otherwise, when you split a string, just access the splitted elements through their index.

Corrected code :

JS

$scope.$watch("excelData", function() {
    var lines, lineNumber, data, length;
    $scope.inviteList = [];
    lines = $scope.excelData.split('\n');
    lineNumber = 0;
    for (var i = lines.length - 1; i >= 0; i--) {
        l = lines[i];

        lineNumber++;
        data = l.split(',');

        var name = data[0];
        var email = data[1];

        $scope.inviteList.push({
            name: name,
            email: email,
            status: "not sent"
        });
    }
});

HTML

  <table>
    <tr>
      <th>Name</th>
      <th>Email</th>
      <th>Status</th>
    </tr>
    <tr ng-repeat="i in inviteList">
      <td>{{i.name}}</td>
      <td>{{i.email}}</td>
      <td>{{i.status}}</td>
    </tr>
  </table>

Your code (especially JS) can still be improved a lot and i encourage you to read docs/tutorials more.

And here is the plunker to your working code.

share|improve this answer
    
Thank you Florian! –  user2656127 Jun 6 '14 at 11:57

I would create a filter to parse the data and reuse it anywhere I want it to. Logic:

app.controller('MainCtrl', function($scope, $filter) {
  $scope.data = 'John Thompson,[email protected]\nRobin Peters, [email protected]\nBill Bob, [email protected]';

  $scope.$watch('data', function(val){
    $scope.inviteList = $filter('csvToObj')(val);
  });
});

app.filter('csvToObj', function() {
  return function(input) {
    var rows = input.split('\n');
    var obj = [];
    angular.forEach(rows, function(val) {
      var o = val.split(',');
      obj.push({
        name: o[0],
        email: o[1],
        status: "not sent"
      });
    });
    return obj;
  };
});

Sample Demo:http://plnkr.co/edit/SOtMMLft3amlVm4RROd0?p=preview

share|improve this answer
    
Thanks! Works nicely, changes my structure a bit , but this is much better! –  user2656127 Jun 6 '14 at 11:51

When you split a string, the return value is an array. I believe that you only have to access the correct indexes of the data array:

app.controller("InviteController", function($scope) {

    //Initliase objects
    $scope.excelData = "";
    $scope.errorMessage = "";
    $scope.inviteList = [];

    $scope.$watch("excelData", function() {

        var lines, lineNumber, data, length;

        lines = $scope.excelData.match(/[^\r\n]+/g);
        lineNumber = 0;

        for (var i = lines.length - 1; i >= 0; i--) {

            l = lines[i];
            lineNumber++;
            data = l.split(/\t/);

            var email = data[1];
            var name = data[0];

            $scope.inviteList.push({
                name: name,
                email: email,
                status: "not sent"
            });

        };

    });

});
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.