0

I have the following controller

angular.module('publicApp')
  .controller('URLSummaryCtrl', function ($scope, $location, Article, $rootScope, $timeout) {
    $scope._url = "";
    $scope._title = "";
    $scope._article = "";
    $scope._authors = "";
    $scope._highlights = [];
    $scope._docType = "";

    $scope.summarizeURL = function(){

        Article.getArticleInfo($scope.url, "").then(
            function(data){

                $scope._url = data.url;
                $scope._title = data.title;
                $scope._authors = data.authors.join(', ');
                $scope._highlights = data.highlights;
                $scope._docType = data.documentType;

                if($scope._docType == 'html'){
                    $scope._article = data.article[0].article;
                }
                else{
                    $scope._article = data.article;
                }

                var _highlights = [];
                $scope._highlights.forEach(function (obj) {
                    _highlights.push(obj.sentence);
                });

                // wait for article text to render, then highlight
                $timeout(function () {
                    $('#article').highlight(_highlights, { element: 'em', className: 'highlighted' });
                }, 200);
            }
        );
    }

and the following view

<form role="form" ng-submit="summarizeURL()">
    <div class="form-group">
      <input id="url" ng-model="url" class="form-control" placeholder="Enter URL" required>
    </div>
    <button class="btn btn-success" type="submit">Summarize</button>
  </form>

<div class="col-lg-8">
  <h2>{{ _title }}</h2>
  <p> <b>Source: </b> <a href="{{_url}}" target="_blank">{{_url}}</a></p>
  <p> <b>Author: </b> {{_authors}} </p>
  <p> <b>Article: </b><p id="article">{{_article}}</p></p>
</div>

When I give a url in the text field initially and click Summarize it works as expected. But when I change the value in the text field and click the button again every thing is updated properly, with the new values, but the $scope._article gets the new value and doesn't remove the old value. It displays both the new and the old value that was there before.

Why is this happening?

EDIT #1: I added more code that I had. I found that when I remove the $timeout(function(){...}) part it works as expected. So now the question is, why is $scope._article keeping the old value and pre-pending the new value?

EDIT #2: I found that $timeout(...) is not the problem. If I change

$timeout(function () {
    $('#article').highlight(_highlights, { element: 'em', className: 'highlighted' });
}, 200);

to

$('#article').highlight(_highlights, { element: 'em', className: 'highlighted' });

it still behaves the same way. So now I'm assuming it's because I'm changing the $scope._article to be something else? What's happening is that I'm displaying the $scope._article value and then modifying what's displayed to contain highlights <em class='highlighed'> ... </em> on what ever I want to highlight.

EDIT #3: I tried to remove the added html before making the request to get new data but that doesn't work either. Here's the code I tried.

angular.module('publicApp')
  .controller('URLSummaryCtrl', function ($scope, $location, Article, $rootScope, $timeout) {
    $scope._url = "";
    $scope._title = "";
    $scope._article = "";
    $scope._authors = "";
    $scope._highlights = [];
    $scope._docType = "";

    $scope.summarizeURL = function(){
        //Remove added html before making call to get new data
        $('.highlighted').contents().unwrap();

        Article.getArticleInfo($scope.url, "").then(
            function(data){ ... }
        );
Haseeb
  • 190
  • 1
  • 6
  • 16
  • 2
    Please provide a [mcve] – charlietfl Oct 25 '16 at 02:09
  • 1
    it's not obvious what is happening here, but there are many nuances with scope inheritance and primitives. you should **always** use a dot in your angular bindings; creating string primitives and binding to those can cause many issues. see http://stackoverflow.com/questions/14049480/what-are-the-nuances-of-scope-prototypal-prototypical-inheritance-in-angularjs for more detail on the subject. – Claies Oct 25 '16 at 02:51
  • If there's any info that I'm missing to provide please let me know. – Haseeb Oct 27 '16 at 00:42

1 Answers1

1

Jquery in angular controllers = headache.

The problem is probably here for you

$timeout(function () {
        $('#article').highlight(_highlights, { element: 'em', className: }, 200);

#article.html() here, is going to give weird output, because angular has it's own sync system and the jquery library you're using has it's own way of working with the DOM. Throw in the fact that asynchronous javascript is already a pain if you're working with multiple things.

What you want instead is to set the html to the angular scope variable before you work with it in jquery so you know what the jquery is working with, i.e.:

$timeout(function () {
        $('#article').html($scope._article);
        $('#article').highlight(_highlights, { element: 'em', className: }, 200);
Jahanzeb Khan
  • 440
  • 4
  • 17
  • Wow! I was about to go crazy on this one. I added the line you suggested and it works like a charm. Thanks a lot! – Haseeb Oct 27 '16 at 02:03