2

I am using the SharePoint JavaScript Object Model within an Angular controller to retrieve data from the Taxonomy (term store). By using $scope.apply, I am able to bind the array to scope and use the values in a dropdown since SharePoint's JavaScript Object Model is not a normal Angular function understood by scope. This works as intended.

Now I need to set the value of the field to the current value stored in the database. This works with the following for dropdown/choice based fields where I retrieve the index of the item via a search of the array. Example:

var currentCategoryIndex = $scope.categoryValues.map(function (e) { return e.value; }).indexOf(currentCategoryValue);
        $scope.vm.selectedCategory = $scope.categoryValues[currentCategoryIndex];

However, I can't access my array within the controller to check for the index (see code below). It does, however, bind the $scope for use in the dropdown via the $scope.$apply.

Something else really odd is if I add an alert, it will start working, like it somehow forces scope back. But using an alert on page load every time just to get the array working is not realistic.

I need to access the array so I can compare against it and get the index so I can set the field value to the correct item currently stored in the database.

Here is the function in my controller. Note that I need to run a sub function to get all the values. This works to create the $scope.termsArray binding that I use in my dropdown, it is the setting of $scope.vm.selectedCategory where the issue is occurring:

var termsArray = [];

    // Query Term Store and get terms for use in Managed Metadata picker stored in an array named "termsArray".

function execOperation() {

        // Current Context
        var context = SP.ClientContext.get_current();
        // Current Taxonomy Session
        var taxSession = SP.Taxonomy.TaxonomySession.getTaxonomySession(context);
        // Term Stores
        var termStores = taxSession.get_termStores();
        // Name of the Term Store from which to get the Terms. Note, that if you receive the following error "Specified argument was out of the range of valid values. Parameter name: index", you may need to check the term store name under Term Store Management to ensure it was not changed by Microsoft
        var termStore = termStores.getByName("Taxonomy1234");
        // GUID of Term Set from which to get the Terms
        var termSet = termStore.getTermSet("1234");
        var terms = termSet.getAllTerms();
        context.load(terms);
        context.executeQueryAsync(function () {

            var termEnumerator = terms.getEnumerator();
            while (termEnumerator.moveNext()) {
                var currentTerm = termEnumerator.get_current();
                var guid = currentTerm.get_id();
                var guidString = guid.toString();
                var termLabel = currentTerm.get_name();

                // Get labels (synonyms) for each term and push values to array
                getLabels(guid, guidString, termLabel);

            }

             // Set $scope to terms array
            $scope.$apply(function () {
                $scope.termsArray = termsArray;
                console.log($scope.termsArray); // DOES NOT LOG ARRAY
            });

          var currentFacilityIndex = termsArray.map(function (e) { return e.termGUID; }).indexOf(currentFacilityGUID);
                console.log(currentFacilityIndex);
                $scope.term.selected = termsArray[currentFacilityIndex];

        }, function (sender, args) {
            console.log(args.get_message());
        });

        // Get labels (synonyms) for each term and push values to array
        function getLabels(termguid, guidString, termLabel) {
            var clientContext = SP.ClientContext.get_current();
            var taxSession = SP.Taxonomy.TaxonomySession.getTaxonomySession(clientContext);
            var termStores = taxSession.get_termStores();
            // The name of the term store. Note, that if you receive the following error "Specified argument was out of the range of valid values. Parameter name: index", you may need to check the term store name under Term Store Management to ensure it was not changed by Microsoft
            var termStore = termStores.getByName("Taxonomy1234");
            // GUID of Term Set from which to get the Terms
            var termSet = termStore.getTermSet("1234");
            var term = termSet.getTerm(termguid);
            var labelColl = term.getAllLabels(1033);

            clientContext.load(labelColl);
            clientContext.executeQueryAsync(function () {
                var labelEnumerator = labelColl.getEnumerator();
                var synonyms = "";
                while (labelEnumerator.moveNext()) {
                    var label = labelEnumerator.get_current();
                    var value = label.get_value();
                    synonyms += value + " | ";
                }
                termsArray.push({
                    termName: termLabel,
                    termGUID: guidString,
                    termSynonyms: synonyms
                });

            }, function (sender, args) {
                console.log(args.get_message());
            });
        }
    };

    // Execute function
    execOperation();

UPDATE: I tried setting the $scope.termsArray = []; per the suggestion below, but it didn't work. What is really odd is that if I have an alert as follows, it somehow forces the console to log/grants me access to the array in the controller.

$scope.$apply(function () {
                $scope.termsArray = termsArray;
                alert("hey");
                console.log($scope.termsArray);
            });

1 Answer 1

2

I found a bit hard to follow your code.

My first guess would be to instantiate the array with empty value before anything else.

$scope.termsArray = [];

This trick tells Angular that this property exists and will exist at later stage.

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

4 Comments

Does the var termsArray = []; do the same thing? Or is $scope.termsArray = []; different instantition since I am binding? I found it odd that I couldn't console.log termsArray without the $scope
termsArray will be a local variable. $scope.termsArray is a property of the object $scope. Nothing stops you of doing var termsArray = $scope.termsArray = [];
I tried using $scope.termsArray = []; and var termsArray = $scope.termsArray = [];, but the array still shows as undefined.
What I don't get is if I have an alert, it forces the console to log. Example: $scope.$apply(function () { $scope.termsArray = termsArray; alert("hey"); console.log($scope.termsArray); });

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.