0

I'm currently having a small issue with a specific loop for showing a button.

I'd like to show a 'suggestBirdname' button depending on two statements: 1. That the user isn't owner of the thread. 2. That the user has not suggested a bird yet on the thread.

This is what I currently have:

// Globelvariable
$scope.showSuggestionButton = false;

var currentSuggestions = res.data.birdsuggestions;
    currentSuggestions.forEach(function(suggestions) {
    if(suggestions.userId === auth.profile.user_id 
             && $scope.capture.birdname==='Unknown') {
        $scope.showSuggestionButton = false;
        } else {
           $scope.showSuggestionButton = true;
        } 
    })

As you can see in the above code, it goes through all my data of the current thread we are on searching through the suggestions. As you can see, I set the default value to $scope.showSuggestionButton = false; seeing that it does not have to be visible unless the above statements are passed.

The problem when going through the loop is: If the current logged in user isn't the last one that posted a suggestion, the loop simply keeps going on, hence setting the statement to true. I need a way to exit the loop once the following statements are triggered: suggestions.userId === auth.profile.user_id && $scope.capture.birdname==='Unknown'

It is probably and easy fix but I just can't seem to wrap my head around it at the moment..

Any help is much appreciated.

For further clarification:

Below I have a button to open a form, to post a suggestion. Though I only want it to be visible if the statements posted above are valid. Going through the data of the post (which has the suggestions linked to it), I want to use the loop above to show the button.

<span class="suggest-birdname-button" ng-if="showSuggestionButton">
                    <span popover-title="{{capture.birdname}}" popover-placement="bottom-left" popover-trigger="mouseenter"
                          popover-append-to-body uib-popover-template="birdInfoPopover.templateUrl" class="suggestion-button-text clickable"
                          ng-bootbox-title="Suggest Birdname"
                          ng-bootbox-custom-dialog
                          ng-bootbox-custom-dialog-template="/partials/model/suggestBirdname.html">Suggest Birdname <span class="glyphicon glyphicon-pencil"></span></span>
                </span>
9
  • Did you try $scope.$watch? Commented Aug 16, 2016 at 12:54
  • Can you elaborate your logic? Commented Aug 16, 2016 at 12:56
  • Are you sure that your first if statement is going through correctly? I'd make sure that your first if statement is evaluating correctly before checking anything else. Commented Aug 16, 2016 at 12:58
  • We probably need some HTML/Template as currently you seem to be setting one button but also need to display more than one button. Commented Aug 16, 2016 at 12:58
  • did not get this line "The problem is, if the user is in the list, but isn't the last one who posted a suggestion, the button is still visible seeing it goes through all the suggestions and takes the last option." Commented Aug 16, 2016 at 13:00

2 Answers 2

1

I think what you need to do is stop looping as soon as you find out that the user has already suggested a bird.

So, instead of looping on all the suggestions, even if you find that user has already suggested a bird, you need to break out of the loop.

I'd tweak your logic to do opposite of what you've done, i.e show suggestion by default, and hide it when you find out that the user has suggested a bird already.

$scope.showSuggestionButton = true;
$scope.checkedAllSuggestions = false;
var currentSuggestions = res.data.birdsuggestions;
for(var i=0; i<currentSuggestions.length;i++) {
    if(currentSuggestions[i].userId ===  auth.profile.user_id && $scope.capture.birdname==='Unknown') { 
   //is $scope.capture.birdname==='Unknown' check needed here, cause it has nothing to do with loop variables?
        $scope.showSuggestionButton = false;
        break;
    }
}
$scope.checkedAllSuggestions = true;

EDIT: You can alter your ng-if condition to show only when all the suggestions are processed. This will solve your initial display of button case. It may seem like a ugly hack, will update this answer when I find a better way to do it.

<span class="suggest-birdname-button" ng-if="showSuggestionButton && checkedAllSuggestions">

If you don't want to use for loop, there are other clean ways of doing this. You can use underscore for such functions.

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

5 Comments

I had this option already, though when the page gets loaded, there is a brief moment where the button is visible
@Borni Updated answer with a hackish way, will find a better solution and update the answer.
This already works though. I'll already mark it up as a good answer. If you find a beter solution, feel free to post it! Thanks
I had to retract the correct answer, seeing it doesn't seem to work when $scope.capture.birdname!=='Unknown' The button still seems to show.
Since the use of this check is not mentioned anywhere in description, I'm not sure how will it affect the condition. Modify the if condition as per your need.
0

You should break your loop when your condition is true.

But there is an easy way with Array.prototype.some() method.

$scope.showSuggestionButton = currentSuggestions.some(function(suggestion){
  return suggestion.userId === auth.profile.user_id && $scope.capture.birdname==='Unknown';
});

$scope.showSuggestionButton value will be set as a true/false according to your if condition.

3 Comments

This doesn't seem to work for me, could you elaborate please?
@Borni I edited the answer, $scope.showSuggestionButton will be true or false(I wrote wrong scope variable instead of this edited because of it.). You may try this code block again.
@Borni Is your if-condition ok?, That code block if any item in your array suitable for that condition , it returns true otherwise false. I think that's what you need exactly.

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.