Less Dirty Way Of Using StartCoroutine?

I’m using a much-needed StartCoroutine when making POSTs and GETs with Unity’s WWW class. I have a script that’s attached to my GameObject, pretty standard, and that script has a property on it that I want to populate with data from my server. I have a working method for doing this but it just feels a little unclean.

Here’s my GameObject script.

public List<Battleschool.Common.Entities.Contract.Battle> Battles;

private IEnumerator initializeActiveBattles()
{
    BattleDirector director = gameObject.AddComponent("BattleDirector") as BattleDirector;

    // pass a copy of myself (this) to the data layer so it can update my property for me
    yield return StartCoroutine(director.GetActiveBattlesByPartyId(PartyId, this));
}

It’s calling into a second class that I’m using as a data layer for my back-end. That code looks like this.

public IEnumerator GetActiveBattlesByPartyId(int partyId, CurrentMatchesScript matchesScript)
{
    WWW www = new WWW(string.Format("http://localhost:12527/api/battle?teamId={0}", partyId));

    yield return www;

    byte[] data = Convert.FromBase64String(www.text.Replace("\"", string.Empty));

    // update the "Battles" property on my GameObject by reference
    matchesScript.Battles = DirectorHelper.DeserializeFromNetwork<List<Battleschool.Common.Entities.Contract.Battle>>(data);
}

What feels dirty is that I have to pass a reference of the GameObject to the data layer class so that it can update by reference of one of the GameObject’s properties.

Am I missing a cleaner way to populate the property on my GameObject while trying to keep the code that accesses my back-end in its own separate class?

How about using a delegate to register callback on your object/s concerned with the result?

public delegate void BattlesByPartyIdResult(BattleDirector caller, Battles result);
public BattlesByPartyIdResult OnRequestSucceeded;

public IEnumerator GetActiveBattlesByPartyId(int partyId, CurrentMatchesScript matchesScript)
{
	WWW www = new WWW(string.Format("http://localhost:12527/api/battle?teamId={0}", partyId));
	yield return www;
	byte[] data = Convert.FromBase64String(www.text.Replace("\"", string.Empty));
	if(OnRequestSucceeded != null)
	{
		OnRequestSucceeded(this, DirectorHelper.DeserializeFromNetwork<List<Battleschool.Common.Entities.Contract.Battle>>(data));
	}
}

Then setup a call back when so when the request is finished it gets notified.

private IEnumerator initializeActiveBattles() { BattleDirector director = gameObject.AddComponent("BattleDirector") as BattleDirector;

director.OnRequestSucceeded += ProcessResult;
    // pass a copy of myself (this) to the data layer so it can update my property for me
    yield return StartCoroutine(director.GetActiveBattlesByPartyId(PartyId, this));
}

private void ProcessResult(BattleDirector caller, Battles result)
{
  //Set your results on this object, validate and clean up delegate as needed
  caller.OnRequestSucceeded -= ProcessResult;
}

This is just the general idea, you would need to figure out how you would want to clean it up and which object owns the deletate. You can this also add a failure callback in the event the web request fails…