4

Considering this sample code, how can it be changed so that it makes the 'something' variable available in the succeshandler function?

var url = _spPageContextInfo.webAbsoluteUrl+"/_api/web/lists";

function addList()
{
    var something = "ABC";
    getData(url).success(successHandler);
}

function successHandler(data)
{
    console.log(something);
    console.log(data);
}


function getData(url)
{

    return $.ajax({
        url:url,
        method:"GET",
        headers: { "Accept": "application/json; odata=verbose" },
    });
}

Update
The topic was marked off topic for not being directly Sharepoint related which I guess is fair, however I've had essentially this same problem for a couple of Sharepoint problems so tried to write it down as generic as possible. Here's the real scenario:

A list of events

A list of registrations containing a lookup to the event.

I want to make a table of all events, including those with zero subscriptions, with event details plus the number of registrations made.

Using Rob's answer it will pass a static variable, but as explained above it needs iterate through a list that was queried before. (get # of registrations for each event). Using the .bind method I am able to pass on the registration data to the next function, which is awesome!

$(function(){   

    var events = _spPageContextInfo.webAbsoluteUrl+"/_api/web/lists/GetByTitle('Events')";
    var registrations = _spPageContextInfo.webAbsoluteUrl+"/_api/web/lists/GetByTitle('Registrations')";    
    var eventsList = [];    

    getData(events + "/items").success(function(data){dataHandler(data);});

    function dataHandler(data)
    {
        for(i = 0; i< data.d.results.length; i++)
        {
            var eventData =  data.d.results[i];
            var key = eventData.Id;
            // Check if this event has already been added to the overview               
            if($.inArray(key, eventsList) == -1)
            {
                //if not get its number of registrations and add it to the overview
                getData(registrations + "/items?$filter=Event/Id eq " + key).success(addEvent.bind(eventData));         
                eventsList.push(key);               
            }           
        }   
    }

    function addEvent(registrationData, eventData)
    {
        var r = registrationData.d.results.length; // number of registrations
        var eventData = this;

        var row = "<tr><td>"+eventData.Title+"</td><td>"+r+"</td></tr>"; // construct the row containing data from both sources         
        $('#overview tr:last').after(row);      
    }

    function getData(url)
    {       
        return $.ajax({
            url:url,
            method:"GET",
            headers: { "Accept": "application/json; odata=verbose" },
        });
    }
});

2 Answers 2

5
function addList()
{
    var something = "ABC";
    getData(url).success(function(data) { 
        successHandler(data, something); 
    });
}

function successHandler(data, something)
{
    console.log(something);
    console.log(data);
}
5

Robs answer works,
But you might as well move the whole function inside the addList scope
(unless the function is called from other functions as well)

The JavaScript .bind() method is the JS way of passing scope

function addList() {
    var something = "ABC";
    getData(url).success( 
       successHandler.bind(something) //bind the function with a different scope
    );
}

function successHandler(data) {
    var something = this ; // this is the scope
    console.log(something);
    console.log(data);
}

For more explanation and usage see:

In the old IE8 days SharePoint needed its own Function.CreateDelegate method:

and you see that in many blogs and code snippets

.bind() is standard JavaScript since IE9

Your Answer

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

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