0

My api returns an array of events (json) with the following property:

event.text

The text property contains a string based on user input, for example companyName, I want to list the text in a ng-repeat loop with a clickable link to the company. (the event.text could be "Dave added a new company Philips" where Philips and Dave are values from a database)

Because the companyname can have html tags that are unsafe e.g.

<a href="somenastyurl">dangerouscompany</a>

angular sanitizes the strings.

However some links should be shown in the front-end, to make sure only save links (created by my api) are shown. I decided to add two return values in the api:

event.links 
event.linknames 

event.links contains links (urls to an item, the urls are always safe and not based on user input they use id's) and event.linknames the names that should be shown in the link. for example:

event.links = ["http://example.com/1","http://example.com/2"]
event.linknames = ["Dave","Philips"]

Ive edited event.text to contain tags like [0] to be replaced with links, a tag [0] should be replaced with a link to event.links[0] with the name of event.linksnames[0]. To replace the tags I made the following code (in my controller after the events are loaded).

angular.forEach($scope.events, function (value, key) {

    var arrayLength = value.links.length;
    for (var i = 0; i < arrayLength; i++) {
        value.Text = value.Text.replace("[" + i + "]", '<a ng-href"' + value.links[i] + '">' + value.linkNames[i]+'</a>');
    }
});

in my view :

 <div ng-repeat="e in events">
      <span >{{e.Text}} </span><br />
</div 

The tag [0],[1] are replaced but the text is still sanitized and in the view the html tags are shown:

 <a ng-href"http://example.com/1">Dave</a> added a new company <a ng-href"http://example.com/2">Philips</a>

instead of the desired result:

 Dave added a new company Philips

where dave and philips are clickable links.

Notes: I know the user could name his company my[0]company but the link would still be safe. Im using angular 1.6.4

How can I make the replaced parts clickable and keep the non replaced part sanitized?

2 Answers 2

1

You can add your own directive for simple unsafe html binding.

var app = angular.module("app", []);
app.controller("ctrl", function($scope) {
  $scope.events = [{
    Text: '<a href="http://example.com/1">Dave</a> added a new company <a href="http://example.com/2">Philips</a>'
  }];
})
app.directive("convertHtml", function() {
  return function(scope, element, attr) {
    scope.$watch(attr.convertHtml, function(value) {
      element.html(scope.$eval(attr.convertHtml));
    })
  };
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
  <div ng-repeat="e in events">
    <span convert-html="e.Text"></span><br />
  </div>
</div>

Sign up to request clarification or add additional context in comments.

4 Comments

But what if the company name contains HTML like the example in my question?
you mean this <a href="somenastyurl">dangerouscompany</a> instead of Philips?
I forgot a major benefit of the list with unsafe links, I can loop them and use WebUtility.HtmlEncode on them before returning them. now the html of the names is shown but the links are valid. If you can add that to the answer i will except it as it still uses your answer.
I'm not getting it. You can up-vote the answer if it helps you and modify it the way you want.
0

use ng-sanitize - Linky Finds links in text input and turns them into html links. Supports http/https/ftp/mailto and plain email address links.

https://docs.angularjs.org/api/ngSanitize/filter/linky

1 Comment

But what if the company name contains HTML like the example in my question?

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.