2

I'm just starting to learn Angular and have been getting to grips well with the basics of it. However I've come unstuck, as my wider knowledge of JS is also pretty limited.

I'm creating a feed that brings in data from a JSON file. One of the items I wish to bring in is a string with HTML inside:

"description": " <p><a href=\"https://www.flickr.com/people/71256895@N00/\">tomylees<\/a> posted a photo:<\/p> <p><a href=\"https://www.flickr.com/photos/71256895@N00/20384585533/\" title=\"American Sweet Potatos IMG_6026\"><img src=\"https://farm1.staticflickr.com/608/20384585533_4141b76f92_m.jpg\" width=\"240\" height=\"180\" alt=\"American Sweet Potatos IMG_6026\" /><\/a><\/p> <p>Going to the farm shop.<br /> Rose Farm Shop, Rose Farm Cottages, Haine Rd, Ramsgate CT12 5AG.<br /> Saturday, 29th August 2015, Ramsgate, Kent.<\/p>",

I'm already parsing the HTML into the view using ngSanitize and ng-bind-html without issue.

Where I am coming unstuck, is that every string of HTML starts with two <p> elements that I don't want to display.

Basically I want create a filter that does this:

var trim = require('trim');
var $ = require('jquery');

angular.module('FlickrFeed')
    .filter('removePara', function () {
        return function(input) {
            var $html = $('<div></div>').append($.parseHTML(input));
            $html.find('p:nth-child(1), p:nth-child(2)').remove();
            var output = trim($html.text());
            return output || 'No description available.';
        };
    });

But, I don't want to use jQuery, as it feels overkill for this tiny part. I'm also aware that my filter won't need to parse my HTML, as ngSanitize takes care of this before it hits the filter (is this why I'm struggling?).

Main question: how do I isolate and remove the first two <p> elements? Obviously the conditional 'No description available' would be an added bonus, but I'll settle for just getting rid of those two paragraphs.

Cheers,

Jamie.

3 Answers 3

1

Behind the scene Angular use jquery, it just wrap the functions differntly

AngularJS Documentation for element

var a = angular.element("<div>").append(angular.element(input))
a.find('p:nth-child(1), p:nth-child(2)').remove()
var output = trim(a.text());
return output || 'No description available.';
Sign up to request clarification or add additional context in comments.

2 Comments

This is what I've been trying to work towards, however I can't seem to get the above code to work. Every time, regardless of which child I select in the brackets, it only removes the second <p>. I suspect it's because the <div> I am targeting is not in the JSON, but rather is the <div> I am binding too? I think the issue stems from when the string is parsed as HTML. In my original, it's parsed within the filter itself. What would be the angular wrapping for parseHTML?
When I checked it the input didnt contain div, so the first row do this for me
0

Just create a String.replace filter, e.g. something like this:

angular.module('FlickrFeed')
.filter('replace', function () {
    return function(input, p1, p2) {
        return input.replace(new RegExp(p1, 'gi'), p2);
    };
});

then use it with your wider knowledge of JavaScript:

<div ng-bind-html="myString | replace:'&lt;p *[^&lt;]+&lt;/p&gt;':''"></div>

This filter is much more reusable and useful. Note that you would need to escape <> for your particular problem.

Comments

0

I would go with very simple CSS approach. Just use this rule to hide unnecessary leadind two paragraphs:

.container p:nth-child(-n+2) {
    display: none;
}

Just use proper selector for list container if course.

1 Comment

Taking the prize for the most efficient way of doing it! This is what I'm using until I can get a JS alternative to work...

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.