How do I Create Event and Bind It?

I am getting an error with BindUObject() on a delegate I’ve created.

I have created a UObject (NetworkObject) to perform GET and POST requests. I would like to catch the HTTP response in another object.

I have created another UObject (GameAccountObject) to access account data on my server and want to add all my accessors and modifiers inside it.

NetworkObject.h

DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FRequestDataReceivedSignature, const FString&, HttpDataReceived);

...(UCLASS)...

//this fires when data is received.
void HTTPOnResponseReceived(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful);

//delegate instance to broadcast bind onReceived
FRequestDataReceivedSignature RequestData_OnReceived;

NetworkObject.cpp

void UNetworkObject::HTTPOnResponseReceived(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful)
{
    RequestData_OnReceived.Broadcast(Response->GetContentAsString());
}

This is my failed attempt to bind the http login response to another function.
GameAccountObject.cpp

void UGameAccountObject::AccountLogin() {
    UNetworkObject netObj;
	FString pJson = netObj.BuildJSONString(tKeys, tValues);
	netObj.HttpPost("myserver.com/login", pJson);

    //ERROR: expression must have pointer type
	netObj->RequestData_OnReceived.BindUObject(this, &UGameAccountObject::AccountLoginComplete);
}

void UGameAccountObject::AccountLoginComplete(const FString& HttpData) {
    //I'd like to handle the login response HttpData here :)
}

I have edited this question now that I have implemented a delegate and am receiving the error ‘expression must have pointer type’.

I really appreciate any help you can offer! I tried to keep it concise but if you need to see any more code please let me know!

If you want to bind a function to another object then the only thing you can do is use delegates.

Here’s an example.

// .h of UNetworkObject

DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FHTTPOnResponseRecievedDelegate, const FString&, HttpData);

class UNetworkObject
{
    FHTTPOnResponseRecievedDelegate HTTPOnResponseRecievedBinder; // custom name
}

// .cpp of UNetworkObject

void UNetworkObject::FunctionThatSendsTheResponse
{
     // calls all binded function
    HTTPOnResponseRecievedBinder.Broadcast("Response");
}

//------------------------------------------------
// .h of UGameAccountObject

class UGameAccountObject
{
    UFUNCTION() // necessary
    AccountLoginComplete(const FString& HttpData);
}

// .cpp of UGameAccountObject

void BeginPlay() // or Constructor
{
   UNetworkObject* Obj;
    Obj->HTTPOnResponseRecievedBinder.AddDynamic(this, &UGameAccountObject::AccountLoginComplete); // binded function must have the same signature as the binder declaration
}

Use Bind instead of BindUObject

Thank you so much for the response. I edited my response a few minutes ago with the delegate implementation. I am now getting ‘expression must have pointer type’.

I tried changing

UNetworkObject netObj;

to

UNetworkObject* netObj;

but then I receive the errors:

netObj->RequestData_OnReceived.BindUObject(this, &UGameAccountObject::AccountLoginComplete);

BindUObject(): class 'FRequestDataSignature has no member “BindUObject”

netObj.HttpPost("url", pJson);

“expression must have class type”

netObj->RequestData_OnReceived.Bind(this, &UGameAccountObject::AccountLoginComplete);
class “FRequestDataReceivedSignature” has no member “Bind”

netObj->HttpPost fixed that error but I am still getting errors with the Bind() or BindUObject() calls.

netObj.HttpPost must be netObj->HttpPost

My bad, it’s actually netObj->RequestData_OnReceived.AddDynamic

You need the actual object for that, created by NewObject

UNetworkObject* netObj = NewObject<UNetworkObject>(); // this is UnrealEngine UObject allocator, C++ uses "new UNetworkObject()"

Don’t use new UNetworkObject()

Amazing!! That totally got rid of syntax errors.

Now this is the final (and very dumb) question. On compile, I receive

uninitialized local variable 'netObj' used

How do I initialize it properly? I swear I am going to spend the night reading C++ pointer tutorials after this. I haven’t done much work with pointers since high school.

Thank you so much!!! I was able to compile with ‘new UNetworkObject’ but its really good to know to use NewObject. I’ve made the changes and I actually understand delegates now. I appreciate the help more than you can imagine :slight_smile:

I changed it after I got your reply. Thanks again :slight_smile:

This is great example, thank you! I have a question since I kinda have modified version of this setup. In my case call to Broadcast method is not happening in implementation file of class where callback is defined as property (UNetworkObject.cpp in your case). I was making API play nicely with Blueprint objects and moment in which I am supposed to ping callbacks is in some other class’ .cpp file. How I ping all callbacks is like this:

static void callbackMethodWhichGetsPinged(FType MyObject) {
    for (TObjectIterator<UMyClassWhereDelegatesAre> Itr; Itr; ++Itr) {
        if (Itr->GetWorld() != nullptr && (Itr->GetWorld()->WorldType == EWorldType::Game || Itr->GetWorld()->WorldType == EWorldType::PIE) && (!Itr->IsPendingKill())) {
            Itr->DelegateName.Broadcast(MyObject);
        }
    }
}

And this actually works pretty well from Blueprint. However, when I do what you did (create UNetworkObject-like object from C++, code from above is not pinging delegate inside of that object.

I assume that if I manage to find a way to drag reference of object which contains the delegate to place where I wanna call Broadcast method on it will do the job, but that would right now make my code really ugly. So wanted to check if you maybe know if there’s a way for me to locate all instances of class which contains delegates (made in C++) and to ping them all?