6

I have a nested JSON structured like this:

[{
"phone_id" : "1",
"phone_name" : "nokia",
"phone_img" : "/src/imgs/nokia.jpg",
"phone_comments" :
    [
                        {
                            "comment_id" : "1",
                            "user_id" : "32508",
                            "comment_date" : "2001-02-01",
                            "user_comment" : "This was the first phone that was rock solid from Nokia"

                        }, 
                        {
                            "comment_id" : "2",
                            "user_id" : "32518",
                            "comment_date" : "2001-02-02",
                            "user_comment" : "Great phone before the smartphone age"

                        },
                        {
                            "comment_id" : "3",
                            "user_id" : "22550",
                            "comment_date" : "2002-04-01",
                            "user_comment" : "Reminds me of my grandpa's phone"

                        },
                        {
                            "comment_id" : "4",
                            "user_id" : "31099",
                            "comment_date" : "2001-05-11",
                            "user_comment" : "It was a crappy one!"

                        }
                    ]
}
]

Display part (works) - I m able to display the phone image on the 1st table column and on ng-click I load the second column with information about the phone with comments. This works perfectly fine.

Deletion (not working) - I have question about deleting comments. I do not want to be delete the whole phone object, but only specific comments. Can I pass something like ???

remove(comment, $index) 

and then have a function that does the following?

$scope.remove = function (index, comments) {
    alert(comments.user_comment + index);
    $scope.comments.splice(index, 1);
}

For reference, the HTML looks something like :

<div ng-app="angularJSApp">
    <div ng-controller="PhoneCtrl">
        <br/><br/><br/>
        <table width="100%" border="1">
            <tr ng-repeat="ph in phones">
                <td width="20%"><a href="#" ng-click="showComments = ! showComments"><img width="50%" ng-src="{{ph.phone_img}}"></a></td>
                <td>
                    <p>Phone Id: {{ph.phone_id}}</p>
                    <p>Phone Name: {{ph.phone_name}}</p>
                    <p>Number of comments: {{ph.phone_comments.length}}</p>

                    <div class="shComments" ng-show="showComments">
                        <p>Search: <input ng-model="query"></p>
                        <table border="1" width="100%">
                            <thead>
                                <tr>
                                    <th><a href="" ng-click="predicate = 'comment_id'; reverse = !reverse">Id</a></th>
                                    <th><a href="" ng-click="predicate = 'user_comment'; reverse = false">Comment</a>
                                        (<a href="" ng-click="predicate = '-user_comment'; reverse = false">^</a>)
                                    </th>
                                    <th><a href="" ng-click="predicate = 'comment_date'; reverse = !reverse">Date</a></th>
                                    <th><a href="" ng-click="predicate = 'user_id'; reverse = !reverse">User</th>
                                    <th></th>
                                </tr>
                            </thead>
                            <tbody>
                                <tr ng-repeat="comment in ph.phone_comments | filter:query | orderBy:predicate:reverse">
                                    <th>{{comment.comment_id}}
                                    <th>{{comment.user_comment}}</th>
                                    <th>{{comment.comment_date}}</th>
                                    <th>{{comment.user_id}}</th>
                                    <th><button ng-click="remove($index, comment)">Remove Comment</button>
                                </tr>
                            </tbody>
                        </table>
                    </div>                  
                </td>
            </tr>
        </table>
    </div>
</div>

P.S: I have been experimenting with AngularJS and I m asking this after having looked for solutions as much as I can. Thanks for your help.

3 Answers 3

9

You could, among other things do the following:

$scope.remove = function (index, comments) {

    delete $scope.comments[index]
}

Upon closer inspection, it would seem that you have a nested data structure there, which means you need two indexes: one for the phone and one for the comment within the phone data structure.

So what you would need is a method along the lines of:

$scope.remove = function (pIndex, cIndex) {

    delete $scope.phones[pIndex].phone_comments[cIndex];
}

One other suggestion I'd put forth is that you should make phones a first-class citizen model and manipulate them through a Service.

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

2 Comments

Thanks for the response. But, that doesn't work for me. Can you please take a look at plnkr.co/edit/gcA5MgshB9wriGM9sKEF?p=preview
The reason it doesn't work is because you need two indexes, one for the phone and one for the the comment within the the phone data structured. I have edited my answer to give you an idea.
2

Thanks to both of you. The first suggestion actually worked.

$scope.removeComment = function (pid, cid) {
    $scope.phones[pid].phone_comments.splice(cid, 1);
};

and the call from the HTML was

<th><button ng-click="removeComment($parent.$index, $index)">Remove Comment</button>

1 Comment

A good practice is to bind $index to variables using ngInit (to avoid referring to the parent scope, as in $parent.$index). So in your example you would use <tr ng-repeat="ph in phones" ng-init="phoneIndex = $index"> and <tr ng-repeat="comment in ph.phone_comments ..." ng-init="commentIndex = $index"> and ng-click="removeComment(phoneIndex, commentIndex)" within your button tag.
1

The issue I found that you call ng-click="remove($index, comment) and pass 2 arguments: $index and selected comment.

However, remove method works with index and list of comments

$scope.remove = function (index, comments) {
    alert(comments.user_comment + index);
    $scope.comments.splice(index, 1);
}

Change ng-click to:

ng-click="remove($index, ph.phone_comments)

The second way without $index:

ng-click="remove(comment, ph.phone_comments)

JS

$scope.remove = function(comment, comments) {     
    comments.splice(comments.indexOf(comment), 1);
 };

[EDIT]*

See working Demo Plunker

1 Comment

Thanks for the response. But. that doesn't work for me. Can you please take a look at plnkr.co/edit/gcA5MgshB9wriGM9sKEF?p=preview

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.