working with CSV files in JavaScript using AngularJS

Currently, I am working on building a simple angular application that can parse CSV input and populate a table with the extracted data.

If you're curious about what I'm trying to accomplish, feel free to check out this Plunker demo - http://plnkr.co/edit/6QFT4AcV4KpiSG23EdOS

Essentially, my goal is to have a <textarea> where users can paste CSV data, which will then be used to populate the table below.

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

Here is the current JavaScript code I have written, but I'm encountering difficulties with: 1. Extracting the email address from the name 2. Updating the $scope.inviteList; with the parsed data

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

    //Initialize 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"
            });

        };

    });

});

Just some basic details:

The CSV format will consist of two columns (name, email) and will be structured like this:

John Thompson,<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="e58f8a8d8ba5918d8a8895968a8bcb868a88">[email protected]</a>
Robin Peters, <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="abd9c4c9c2c5ebdbcedfced9d885c8c4c6">[email protected]</a>
Bill Bob, <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="7113181d1d31131e135f121e1c">[email protected]</a>

Answer №1

There are several issues in your code:

  • Instead of using regex, you can simply split the input string for easier processing.
  • The structure of your HTML is incorrect - td should be nested inside tr.
  • Make sure to clear your array before adding new elements to it.
  • Ensure that variables used inside ng-repeat are properly scoped and defined.
  • Avoid using unscoped variables whenever possible.

When splitting a string, access its parts using their respective indexes.

Here is the 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>

There is still room for improvement in your code, especially in the JS part. I recommend exploring more documentation and tutorials.

Here is a link to a plunker with your updated code: Plunker.

Answer №2

To efficiently manage and manipulate data in various parts of my application, I would implement a filter for parsing the data. Here's how it works:

app.controller('MainCtrl', function($scope, $filter) {
  $scope.data = 'John Thompson,<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="6a000502042a1e0205071a19050444090507">[email protected]</a>\nRobin Peters, <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="41332e23282f013124352433326f222e2c">[email protected]</a>\nBill Bob, <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="3b595257577b59545915585456">[email protected]</a>';

  $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;
  };
});

Check out a Demo:http://plnkr.co/edit/SOtMMLft3amlVm4RROd0?p=preview

Answer №3

When a string is split, the resulting output is an array. It's important to know how to access specific indexes within the data array:

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

    //Initialize variables
    $scope.inputData = "";
    $scope.errorMessage = "";
    $scope.userList = [];

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

        var lines, lineNum, data, length;

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

        for (var j = 0; j < lines.length; j++) {

            var line = lines[j];
            lineNum++;
            data = line.split(/\t/);

            var username = data[0];
            var password = data[1];

            $scope.userList.push({
                username: username,
                password: password,
                loggedIn: false
            });

        };

    });

});

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Ensure that PHP form validations are checked when submitting the form using jQuery

I have created a form in HTML with basic verification. Here is the code: <form class="" action="submit/save" method="POST" enctype="multipart/form-data" id="submit_form"> <input class="form- ...

Enable modification of form field once a personalized dynamic stamp has been applied

I currently have a functional custom dynamic stamp that includes multiple input fields prompting the user. My goal now is to integrate a form text field onto the stamp after it has been rendered. For example, if someone stamps everything except for the led ...

Retrieve the input file from a different perspective

We are utilizing Razor in combination with MVC and AngularJs. In my form, there is an option to choose an image from a . You can either directly upload the selected image by clicking the submit button or proceed to another view to provide additional infor ...

What is the best way to adjust a map to completely fill the screen?

I am experiencing an issue with my Openlayer map not fitting to full screen automatically. Despite trying various settings, I am unable to resolve this issue. Can anyone suggest what might be causing this problem? Thank you in advance https://i.stack.imgu ...

I am encountering an issue while trying to update SQL data from within a Node.js

Using a for-loop to update SQL command is common practice. Here's an example: for(var i=count1; i < count2;i++){ Book.TimeStart = Times[I] console.log(Book.TimeStart) sql = sql + `UPDATE projectroom.Details SET BookingId = `+Book.Bo ...

Exploring the contents of a dropdown menu by navigating through a tree structure in React JS

A unique custom component has been developed, featuring a dropdown with a tree-like structure inside that allows users to search for values. However, it seems that the search function only works after reaching two levels of the tree structure. Currently, ...

Iterate through every item in Google Docs and duplicate them onto a fresh page

I am currently developing a script that allows teachers to easily create translations of documents stored on Google Drive. The script is expected to go through the body elements of the document, translate the text, and paste it onto a new page appended to ...

The View remains unchanged following a $http.get() request

Recently, I encountered an issue while following a tutorial. The tutorial demonstrated a factory making a $http.get() request and returning data that was supposed to be assigned to a controller's $scope variable ($scope.classifieds). However, even tho ...

Struggling with displaying a PDF file from the local directory in a NextJS application

I've been facing trouble importing and displaying my resume, a local file, within a react component. The code import myResume from '../assets/pdfs/myResume.pdf' is resulting in the error: Error: Cannot find module '../assets/pdfs/myRes ...

Steps for implementing a reset button in a JavaScript slot machine game

I need assistance with implementing a reset button for my slot machine game prototype written in JS. I attempted to create a playAgain function to restart the game by calling the main game function, but it's not working as expected. Do I need to pass ...

The function document.getElementById(...) is failing to retrieve the text data from the table as expected

Greetings fellow HTML and JavaScript novice! I've got a table with input cells in the bottom row: <table class="convtbl" id="table1"> <tr> <td>Distance 1 (in miles)</td> <td>Time ...

Executing a query with a `has many` relationship in MongoDB: Step-by-step guide

In my setup with Node, Express, and backbone, I am successfully retrieving records from MongoDB collections using simple queries. However, I am struggling to understand how to query more complex data, such as the one below: db.employees.aggregate( [ ...

Error in Uploading Files with AngularJS - Uncaught SyntaxError: Unexpected token

I'm having trouble uploading an image file using Angular and PHP, specifically at the app.service Error line: app.service('fileUpload', ['$https:', function ($https:) { Code app.service('fileUpload', ['$https:&ap ...

The compatibility of Datatables responsive feature with ajax calls appears to be limited

I recently started using the datatables plugin and have encountered an issue with responsive tables. While I successfully implemented a responsive table and an AJAX call on a previous page, I am facing difficulties with it on a new page for unknown reasons ...

What steps can I take to ensure my website is optimized for a seamless viewing experience on all mobile devices

Could you please check out the link on your smartphone and let me know if it looks a bit off to you? I have centered everything and the website looks fine on desktop, but on my iPhone 5S, it doesn't seem to display properly. Is there a way to make it ...

Unpredictable term pulled from the Javascript/Ajax content

Can someone help me figure out how to randomly select just one word from a block of text using JavaScript? Here's the code I've been working with: function someFunction() { // need help here var word; $.ajax({ async: false, typ ...

What strategies are effective for handling state reactively in Vuex?

Currently, I am facing an issue with my vuex store. I have implemented two different actions in my store, one being reactive and the other not. However, I specifically need the loadSlidesEach() action to be reactive so that the data gets updated accordingl ...

Material UI: Dynamic font scaling based on screen size

If I were to adjust the font size responsively in Tailwind, here's how it would look: <div className="text-xl sm:text-4xl">Hello World</div> When working with Material UI, Typography is used for setting text sizes responsively. ...

Issue with setting GeoJSON in jQuery callback using Mapbox`

Using Jquery, I am trying to retrieve geojson points data (which will set markers on a map) from a database. function remm(id){ $.ajax({ type: "POST", url:"geojson2.php", data:{ u_id:id[0], t_id:id[2] }, success: functi ...

What is the purpose of employing useMemo in the Material-UI autocomplete documentation?

My focus is on this specific demo in the autocomplete documentation. In the google maps example, there is a throttled function that is returned from a useMemo with an empty array as the second parameter. However, it raises the question of what exactly is ...