0

So I'm working on a personal portfolio for myself with a few projects I've done for my intro web dev class. Since we've been practicing data driven content websites and webapps in class, my professor wanted us to do something similar, either by putting our data in a cloud based data storage or in a .csv file. I decided to go the .csv file route.

After creating the .csv file, I'm using Papa Parse to read in the .csv file data into a usable format for my website and then I'm using angular to loop through the data and put the relevant parts on the page. The only section of my website that uses this data is the projects section on the home page.

Anyway, my problem is that sometimes when I load the page, either for the first time when I open the URL, or when I've switched to the home page from the about, or contact page, I've noticed that the content doesn't show up and I have to reload the page to get the gifs and text to show up. Here are some screen shots: What it should look like and What it sometimes looks like. I'll also including a link to my site in the comments (because I don't have 10 reputation yet, so I can't post more than two links) if you'd like to see for yourself. (It's still a work in progress, so I'll admit I'm a little embarrassed about posting it, but I'd really like to solve the problem).

Also, here's the HTML where this data is being used for the page:

<div class="projects">
<h1 class="projects-heading">Projects</h1>
<div class="container projectContainer" ng-repeat="project in projects">
    <div class="row">
        <div class="col-xs-12 col-md-6">
            <img class="projectGif" ng-src="{{project.gifUrl}}" ng-hide="projects.length < 0">
        </div>
        <div class="col-xs-12 col-md-6">
            <h4 class="project-info proj-title">{{project.title}}</h4>
            <p class="project-info proj-body">{{project.description}}</p>
            <a class="project-info" target="_blank" href="{{project.link}}">View the live site</a>
        </div>
    </div>
    <!-- Creates divier line between each separate project -->
    <hr class="project-split">
</div>

My controller:

app.controller('HomeController', function($scope){
Papa.parse("data/home.csv", {
    download: true,
    header: true,
    complete: function(results) {
        $scope.projects = results.data;
    }
});

});

  • my portfolio: http://students.washington.edu/jgb93/info343/portfolio/#/home –  Nov 26 '15 at 06:59
  • ng-hide="projects.length < 0". This line seems redundant. Anyway the implementation seems correct. It sounds like a timing issue. Could you post your controller? – Simone Zandara Nov 26 '15 at 07:10
  • @xbirkettx Oh yeah, totally redundant. That's something I was testing with and forgot to delete. Thanks for catching it! But yeah, I was thinking it might be a timing issue, I just don't know how to solve for that. If you could help, that would be fantastic! I'm posting my controller right now! –  Nov 26 '15 at 07:35

2 Answers2

1

I don't know this Papa but I think this is an asynchronous call therefore it runs outside the Angular loop. Try this

complete: function(results) {
    $scope.projects = results.data;
    $scope.$apply();
}

Angular has its own event loop which runs each time Angular knows that it must run. That happens when the code which modifies the state runs within Angular. When the loop runs, all variables, binding and rendering is also updated.

Here you are using an external library Papa which simply runs an Ajax request. The request is sent within Angular but the result callback is handled outside due to asynchronousity. Therefor you must force Angular to update its data. What $scope.$apply() does is to force the event loop to update only for this controller.

Remember to do that each time you run code which is not inside Angular but will interact with Angular. That is valid for example for 'onclick' or jQuery events or just any code outside the Angular scope.

Simone Zandara
  • 9,401
  • 2
  • 19
  • 26
  • It looks like it might have worked - it's a bit hard to tell because the only thing I can do to test it is repeatedly refresh the page. I'll keep testing. But if this did solve it, would you mind explaining what adding that line did? @xbirkettx –  Nov 26 '15 at 17:41
  • Awesome! Thank you. Looks like I haven't had any problems since I've added the line of code! –  Nov 26 '15 at 19:03
0

I have the similar problem in angular 8, the @simone answer gave me an Idea to solve it.

Here is the code used to solve in angular 8

public parseCSV(file: File) {
    let _self = this;
    Papa.parse(file, {
      error: function (err, file, inputElem, reason) {
        console.log(err);
      },
      complete: function (results) {
        _self.apply(results.data);
        console.log("Finished:", results.data);
      }
    });
  }

public apply(data) {
    this.dataSource = data;
  }
Krish
  • 724
  • 7
  • 17