question

brendan avatar image
brendan asked

Anyway to "Wait" for Result of an API call?

sketchwork
started a topic on Thu, 09 July 2015 at 9:54 AM

I have an issue where I'm login on then retrieving some player data to display. My problem is that my display of the retrieval code is being fired before the retrieval api has finished.

Unity Example:

1) Login with PlayFab.

2) Upon successful login load next scene.

3) API call to get playerdata

4) Display the data.

Is there a way to yield till the api call has finished?

Thanks.

10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

brendan avatar image
brendan answered

Best Answer
Brendan Vanous said on Sun, 12 July 2015 at 4:08 PM

All of our API calls in the Unity SDK use callbacks to notify when the call has completed successfully (and error call backs for when there's an error). So in general, that's the approach I would recommend:

  • Login with PlayFab

  • In your callback function, check the result and proceed to load the next scene if there are no issues

  • Call to get the player's data

  • In your callback function, check that the data was returned successfully and use that info for the display

Brendan


1 Comment
Brendan Vanous said on Sun, 12 July 2015 at 4:08 PM

All of our API calls in the Unity SDK use callbacks to notify when the call has completed successfully (and error call backs for when there's an error). So in general, that's the approach I would recommend:

  • Login with PlayFab

  • In your callback function, check the result and proceed to load the next scene if there are no issues

  • Call to get the player's data

  • In your callback function, check that the data was returned successfully and use that info for the display

Brendan

10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Jonathan Fisher avatar image
Jonathan Fisher answered

I've been struggling with this exact issue, waiting for the plafab api to return user data, without using a generic waitforseconds in a coroutine. Would anyone be able to post a simple code example of calling playfab's PlayFabClientAPI.GetUserData, then waiting for the data to be returned, then calling a subsequent generic method? Any help would be appreciated!

1 comment
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

brandon@uprootstudios.com avatar image brandon@uprootstudios.com commented ·

@Jonathan Fisher Can you post your code? The PlayFab SDK for Unity will automatically return the result as a callback for whatever API you call. So, for example, if you're doing GetUserData:

PlayFabClientAPI.GetUserData(new GetUserDataRequest{
    PlayFabId = yourUsersID
},
result => {
    //this is your result callback
    //do something with the result here
    var userData = result.UserData;
},
error => {
    //this is your error callback
    //do something with the error here
    NotifyUserOfError(error.ErrorMessage);
}  

Hope that helps!

0 Likes 0 ·
Jonathan Fisher avatar image
Jonathan Fisher answered

Hi, Brandon - thanks so much for taking the time to help me out!

I did ultimately solve it JUST last night (embarrassingly this has taken like a week). I did indeed use the general idea you posted, however my issue is that I was trying to retrieve a set of user data items in a for loop (not sure if there is a better way in the key system). Essentially, I'm having each player import a set of asset bundles specified by another player, so that is a list of assetbundle names plus a corresponding prefab (each one is its own prefab). It's actually a multiplayer lecture presentation platform.

My challenge is that the for loop isn't paused by the playfab API call, and I just couldn't figure out a good way to load a long list of numbered key data. Without any delay, the set of items couldn't be loaded with any certainty, and things would just move on. Ultimately, I inserted a yield return waituntil after each loop.

Here's what I came up with (and I am doing this in a coroutine called by something else). Is there a better way to do this? Thanks!!

   IEnumerator GetSlideNames()

    {

        Debug.Log("Executing GetSlideNames");


        for (int i = 0; i < pNumSlides; i++)

        {

            Debug.Log(i.ToString());

            dataKey = "Room" + i.ToString() + "DataObj1ItemName"; 


            PlayFabClientAPI.GetUserData(new GetUserDataRequest()

            {

                PlayFabId = PlayFabEyeDee, //please ignore dumb nomenclature

                Keys = null

            }, result => {

                Debug.Log("Got user data:");

                if (result.Data == null || !result.Data.ContainsKey(dataKey)) Debug.Log("No " + dataKey);

                else Debug.Log(dataKey + ": " + result.Data[dataKey].Value);

                pAddresses.pSlideList.Add(result.Data[dataKey].Value);


            },



            (error) => {

                Debug.Log("Got error retrieving user data:");

                Debug.Log(error.GenerateErrorReport());

            });


            yield return new WaitUntil(() => pSlideList.Count > i);

        }



        StartCoroutine(GetRoomAvatarArrayName()); // this then moves on to my next set of data 

        yield return null;



    }





1 comment
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

brandon@uprootstudios.com avatar image brandon@uprootstudios.com commented ·

@Jonathan Fisher Ultimately, that doesn't seem like too bad of a way to accomplish what you want, as long as it's working for you. Although, do you know the Keys of the data fields you want to get from the user? If so, you can populate those in the call and you wouldn't need to parse the result (unless it's empty).

Alternatively, you could just have Cloudscript parse the keys and only return the ones you need to the client.

0 Likes 0 ·
Jonathan Fisher avatar image
Jonathan Fisher answered

@Brandon Phillips Yeah, it was a bit of a hack :) Unfortunately, depending on the room the player is joining, there are a variable number / names of the KVPs to be loaded, so it's not really practical (until I restructure the project in a smarter way) to pre-populate the fields. The cloudscript option you mention sounds interesting - will have to look into that. Can you recommend any tutorials / examples? Thanks again for taking the time!

10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Write an Answer

Hint: Notify or tag a user in this post by typing @username.

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.