Waiting for a coroutine to finish before continuing the function.

I’m writing some code for a web service to retrieve info from my database. The only problem is the script is finishing before the data from the website is retrieved. How can I pause the function after web.Load(url); and wait for the data to be loaded then continue?

    public T Get<T>(Stats type, string id) 
    {
		url = "http://localhost/webservice.php?query="+AESE.Encrypt(string.Format("SELECT {0} FROM player WHERE fbId='{1}';", type.ToString(), id));
		GameObject go = new GameObject("WWWAPI");
		WWWAPI web = go.AddComponent<WWWAPI>();
		web.Load(url);
		text = AESE.Decrypt(web.text);
		//IDictionary<string, object> temp = JSON.ParseJSON(text);
        return (T)Convert.ChangeType(text, typeof(T));
    }

and

public class WWWAPI : MonoBehaviour{
	public string text = string.Empty;
	public bool isDone = false;
	private string url = string.Empty;

	public void Load(string url)
	{
		this.url = url;
		StartCoroutine("LoadSite");	
	}
	private IEnumerator LoadSite()
	{
		url = url.Replace(" ", "%20");
		WWW web = new WWW(url);
		yield return web;
		text = web.text;
		isDone = true;
	}
}

Yield WaitForSeconds I use as a coroutine to halt a function for however long you want, then continue.

The yield return waitforseconds will work in the IEnum but not in a void or any other type

You need to make your Load function like this:

public IEnumerator Load(string url)
{
       this.url = url;
       yield return StartCoroutine("LoadSite");	
}

That way, the Load function is not exited until the LoadSite() function has completed. If you don’t do it that way, your Load function will start the LoadSite() function, and then move on (in this case, exit) before LoadSite is done.

2 Likes

When I try to call web.load it doesnt even call this.url = url; It seems to just exit the function.

OK, so you need to put some print statements into your functions to see if things are actually getting called. It’s a pain in the butt (and a decent debugger may circumvent thid approach- I don’t know any) to do the print thing, but it will at least help you understand if the LoadSite function is being called.

Rember too that if you have in fact made the Load function return a IEnumerator instead of being a void return, you will need to make sure that any “calls” to this function use StartCoroutine(“Load”) rather than just Load().

I was stepping through the program and it called LoadSite and stepped to the { then stepped back to the function then stepped back to where it was called and skipped over it.

And if i call StartCoroutine(web.Load(url)); or StartCoroutine(“web.Load(url)”); i get a null reference error.

This might be better. How can i call a function that can connect to my webservice then return the value?

If you want to wait for it to finish before continuing then why make it a Coroutine at all? :slight_smile:

That being said:
yield return StartCoroutine(“LoadSite”); should do the trick.

Alternately, increase the scope of your web variable and check its null-ness in Update().

EDIT: Just read the entire OP (shame on me!) and realized you’re calling it from another class so it wouldn’t be as simple as yielding LoadSite. I would do the null check instead.

What’s with the strings?

yield return StartCoroutine(LoadSite()); IIRC