3

I'm pulling information from an Excel spreadsheet and trying to check the rows against data from a SharePoint list to find duplicates.

The executeQueryAsync() in the itemIsDuplicate() function is causing the promise to try to resolve before the promise is returned resulting in the error message "Unable to get property 'then' of undefined or null reference"

Here are the relevant sections of code:

 for (var i = 0; i < rows.length; i++) {               
            var newItem = {
                week: rows[i].Week._Default,
                customer: rows[i].Customer._Default,
                resource: rows[i].Resource,
                title: rows[i].Title._Default,
                category: rows[i].Category._Default,
                notes: rows[i].Notes._Default,
                plannedHours: rows[i].PlannedHours._Default,
                percentComplete: rows[i].PercentComplete._Default,
                extID: rows[i].ExtID._Default,
                actualHours: rows[i].ActualHours._Default,
                type: rows[i].Type._Default,
                dmRequest: rows[i].DMRequest._Default
            }

            itemIsDuplicate(newItem).then(function (isDuplicate) {
                if (!isDuplicate) {
                    newItems.push(newItem);
                }

                else {
                    duplicates.push(newItem);
                }

            })
        }

        $.when.apply($, promises).done(function () {
            //process results...
        } 

function itemIsDuplicate(item, newItems) {

            var deferred = new $.Deferred();
            promises.push(deferred);
            var isDuplicate = false;
            var duplicateQuery = new SP.CamlQuery();
            duplicateQuery.set_viewXml(
                '<View><Query><Where>' +
                    '<And>'+
                        '<Eq>' +
                            '<FieldRef Name= \'Week\' />' +
                            '<Value Type= \'DateTime\' IncludeTimeValue=\'FALSE\'>' + new Date(item.week).toISOString() + '</Value>' +
                        '</Eq>' +
                        '<And>' +
                            '<Eq>' +
                                '<FieldRef Name= \'LIS_x0020_Analyst\' />' +
                                '<Value Type= \'Text\'>' + item.resource + '</Value>' +
                            '</Eq>' +
                            '<Eq>' +
                                '<FieldRef Name= \'Title\' />' +
                                '<Value Type= \'Text\'>' + item.title + '</Value>' +
                            '</Eq>' +                          
                        '</And>' +
                    '</And>' +
                '</Where></Query></View>'
            )

            var duplicateItemsColl = worklist.getItems(duplicateQuery);
            clientContext.load(duplicateItemsColl);
            clientContext.executeQueryAsync(
                function () {
                    if (duplicateItemsColl.get_count() > 0) {
                        isDuplicate = true;
                    }

                    deferred.resolve(isDuplicate);
                    return deferred.promise();
                },    
                function (sender, args) {

                    console.log("Error message here...")
                }
            );                     
        }

Does anybody have a good solution to avoid this problem?

I'm pretty new to JavaScript development in SharePoint, and the use of $.Deferred, so this might be simple but the answer has eluded me so far. Thanks.

1 Answer 1

7

You need to return the promise in the itemIsDuplicate() function, not the success callback. Just move return deferred.promise(); to the end of the function. You'll might want to either add deferred.resolve() to the error callback, or a deferred.reject() if you need to execute something after an error occurs.

Code should be as such:

function itemIsDuplicate(item, newItems) {
    var deferred = $.Deferred(),
        isDuplicate = false,
        duplicateQuery = new SP.CamlQuery();

    duplicateQuery.set_viewXml( '<your caml query>' );

    duplicateItemsColl = worklist.getItems(duplicateQuery);
    clientContext.load(duplicateItemsColl);
    clientContext.executeQueryAsync(
        function(){ deferred.resolve(duplicateItemsColl.get_count() > 0); },
        function(sender, args) { deferred.reject(sender, args.get_message()); }
    );
    return deferred.promise();
}

And whenever you call it:

var checkDuplicate = itemIsDuplicate(newItem);
promises.push(checkDuplicate);
checkDuplicate
    .done(function(isDuplicate) {
        if(!isDuplicate) newItems.push(newItem);
        else duplicates.push(newItem);
    })
    .fail(function(sender, error) {
        console.error(sender, error);
    });
$.when.apply($, promises).done(function () {
    //process results...
} 
1
  • Thabnk You for example!
    – Gennady G
    Commented Feb 5, 2019 at 13:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.