0

I have read documentation and googled this a lot but can't seem to figure it out.

When I select an item in my select drop down it doesn't bind to my ng-model="chosenVariant". console.log always has $scope.chosenVariant come back undefined. I have tried created a object called cartItemData, setting chosenVariant as a data field inside it and pushing $scope.itemForShoppingCart with itemVariant: cartItemData.chosenVariant but that didn't work either.

HTML

<div class="col-sm-3 my-3" ng-repeat="i in items">
    <div class="card text-center">
        <div class="card-header">{{i.itemName}}</div>
        <div class="card-body">
            <img class="responsiveBioImg" ng-src="{{i.itemImage}}">
        </div>
        <div class="card-footer">
            <a type="button" class="far fa-eye fa-3x gglplyIconColor"
                ng-click="selectItemForItemModal(i)" data-toggle="modal"
                data-target="#itemModal"></a>
        </div>
    </div>
</div>

Modal header and body data is populated with $scope.selectedModalItem

<div class="modal-footer"></div>
<nav class="navbar navbar-expand">
    <ul class="navbar-nav ml-auto">
        <li class="nav-item mx-2" id="sizesOptions"
            ng-if="selectedModalItem.hasVariant == true"
        >Options:
            <select ng-model="chosenVariant"
                    ng-options="variant for variant in selectedModalItem.variants">
            </select>
        </li>
        <li class="nav-item mx-2"><b>${{selectedModalItem.itemPrice}}</b>
            USD</li>
        <li class="nav-item mx-2"><a type="button"
            class="fas fa-shopping-cart navTextPink fa-2x"
            ng-click="addToCart()"></a></li>
    </ul>
</nav>

JS

$scope.getInventory = function() {
    $http.get('/AGRwebapp/webapi/agrapi')
        .then(
            function(response) {
                $scope.items = response.data;
            }
        );
}

$scope.selectItemForItemModal = function(selectedItem) {
    $scope.selectedModalItem = {
        itemId: selectedItem.itemId,
        itemName: selectedItem.itemName,
        itemPrice: selectedItem.itemPrice,
        itemDesc: selectedItem.itemDesc,
        itemImage: selectedItem.itemImage,
        hasVariant: selectedItem.hasVariant,
        variants: selectedItem.variants
    };
}

$scope.addToCart = function() {
    $scope.itemCartId++;
    $scope.itemForShoppingCart = {
        tempId: $scope.itemCartId,
        itemName: $scope.selectedModalItem.itemName,
        itemPrice: $scope.selectedModalItem.itemPrice,
        itemVariant: $scope.chosenVariant
    }
    console.log($scope.chosenVariant);
    $scope.shoppingCart.push($scope.itemForShoppingCart);
}
georgeawg
  • 48,608
  • 13
  • 72
  • 95
  • 2
    New AngularJS developers often do not realize that `ng-repeat`, `ng-switch`, `ng-view`, `ng-include` and `ng-if` all create new child scopes, so the problem often shows up when these directives are involved. This issue with primitives can be easily avoided by following the "best practice" of always have a '.' in your ng-models. – georgeawg Jan 28 '21 at 12:11

1 Answers1

1

I managed to reproduce your issue and also to solve it.

You need to replace your ng-if with ng-show like so:

<div class="modal-footer"></div>
        <nav class="navbar navbar-expand">
            <ul class="navbar-nav ml-auto">
                <li class="nav-item mx-2" id="sizesOptions"
                    ng-show="selectedModalItem.hasVariant">Options:
                    <select ng-model="chosenVariant"
                            ng-options="variant for variant in selectedModalItem.variants">
                    </select>
                </li>
                <li class="nav-item mx-2"><b>${{selectedModalItem.itemPrice}}</b>USD</li>
                <li class="nav-item mx-2">
                  <a type="button"
                     class="fas fa-shopping-cart navTextPink fa-2x"
                     ng-click="addToCart()">
                  </a>
                </li>
            </ul>

        </nav>

ng-if will remove elements from the DOM, this way you can't bind an unexisting element. This problem is solved using ng-show.

I recommend to explore a bit about the differences between the two

Vali D
  • 511
  • 1
  • 6
  • 20
  • I replaced ng-if to ng-show and it still isn't working. My console log for chosenVariant still comes back undefined. – JeremyGiffARCA Jan 28 '21 at 05:27
  • Do you have Varients in the selectedItem? I used some mock data and it worked fine for me. Perhaps you can create a running example on Stackblitz or jsfiddle so it is easier to address. – Vali D Jan 28 '21 at 07:32
  • It was my mistake. This worked thank you! – JeremyGiffARCA Jan 29 '21 at 03:28