proyecto26 / RestClient

🦄 A Promise based REST and HTTP client for Unity 🎮
https://assetstore.unity.com/packages/slug/102501
MIT License
1.24k stars 173 forks source link

Running multiple POST requests using Promise.ThenAll returns an IEnumerable of ResponseHelper objects, not all of them returned Data #228

Open KevinAnggrek opened 2 years ago

KevinAnggrek commented 2 years ago

I am using the RestClient in Unity to make requests to the Microsoft Graph API. So far the RestClient has worked remarkably well and I really enjoy using it.

Recently, I tried doing multiple GET requests to one of the Graph API's endpoint by using the Promise.ThenAll method. In theory, the ThenAll method will chain an enumerable of Promises and will return a new Promise for a collection of resolved results.

I have a method called GetSharePointListColumns that I use to make the GET request:

public IPromise<ResponseHelper> GetSharePointListColumns(string listId)
    {
        string endPoint = $"https://graph.microsoft.com/v1.0/sites/{_siteId}/lists/{listId}/columns";

        return GraphGetAPICall(endPoint);
    }

The GraphGetAPICall is a method that will do the request:

private IPromise<ResponseHelper> GraphGetAPICall(string endPoint)
    {
        RestClient.DefaultRequestHeaders["Authorization"] = $"Bearer {_accessToken}";

        RequestHelper request = new RequestHelper
        {
            Method = "GET",
            Uri = endPoint,
        };

        return RestClient.Request(request);
    }

In my main code, I chain multiple GetSharePointListColumns in the following manner:

previousPromise.ThenAll(ids =>
                {
                    parentListId = ids.Item1;
                    childListDict = ids.Item2;

                    return childListDict.Select(kvp => GetSharePointListColumns(kvp.Value));
                }).Then(allRes =>
                {
                    ....
                }

The childListDict is a Dictionary that in this case will contain 3 entries, basically, I would like to run a GET request for each entry in that Dictionary. The resolved values are all stored in the allRes variable (which, as expected, is an IEnumerable). However, when I debug each of the ResponseHelper in the enumerable, only one of them contains the Data, the other two ResponseHelper will always have null Data. I repeat the debug multiple times and I notice that only one of the ResponseHelper will have a data, and as I have 3 entries in the Dictionary and thus 3 GET requests, the single successful ResponseHelper does not always come from the same entry or GET request, sometimes the single successful ResponseHelper is from the first GET request, sometimes it is the second or the third.

The two ResponseHelper with null Data will also have System.ArgumentNullException: Value cannot be null. Parameter name: _unity_self exceptions on the Error, Headers, and StatusCode properties of the ResponseHelper 1

On the other hand, the successful ResponseHelper looks like this: 2

Just for testing, I tried doing only one request at a time, one for each entry in the dictionary, and all of them can return a ResponseHelper with the correct Data. By doing one request at a time, I mean using Promise.Then followed by only a single GetSharePointListColumns.

Thus, my question is how to actually do multiple requests like this? Is there any part that I did wrongly? Are there any issues with UnityWebRequest? Thanks a lot!