Problem with multipage web app

Hello

I have a very simple web app that a user fills somedata and the app send a mail using smtpsocket.

The first version was a simple form and worked fine, but later i decided to present the user different forms depending of the user using a computer or a phone.

My problem is with the phone one. As the screen is smaller i splitted the form in two: for this example call them FormDate and FormData.

The first one (FormDate) asks for a date using WebDatePicker from Jeremie Leroy, a date/time (using WebPopupMenu) and a then user press a button that showns the second one (FormData). Here the user fills his email, name, and observations.

The mail (in the mobile Forms) is send using an SMTPsocket control added to the form (Called here MailSocket2)

My problem is that want to clear the forms after the email sucessfuly sent. And added the MailSent event to the MailSocket2 (SMTPsocket) control:

MobileSelectDateForm.DatePicker1.SelectedDate=nil MobileSelectDateForm.SelectorFecha.DeleteAllRows

And then, when the event is triggered, the app stop with a NilObjectException

If i add a button to the second form that performs the same commands (the ones to clear the first one) it works without error, but with them executed from the MailSent event, the NilObjectException happens.

So:

[quote]DataForm.Button.Action -> Cleans the first form without problem
DataForm.MailSocket2.MailSent -> stops with NilObjectException[/quote]

I also tried to create a method in the first form (DateForm) named ClearForm and do the cleans from it (using Self… and DateForm…) and calling the method from the MailSocket2.MailSent event, but NilObjectException happens also.

Can anyone help/guide me on what i’m doing wrong?

Thanks!

You should place your SMTP socket on Session instead. That way it won’t become nil when the WebPage changes.

Thanks, Michel, but i don’t know how to place it in Session, can you guide me? As a property perhaps?, if so, don’t know how to use it.

Yes, add the SMTPSocket as a property.

mySMTPSocket as SMTPSocket

Initialize it in Session Open as

mySMTPSocket = New SMTPSocket

And then instead of simply calling it like mySMTPSocket, prefix it with Session :

Session.mySMTPSocket

It should be pretty easy to refactor your present code.

[quote=336639:@Michel Bujardet]Yes, add the SMTPSocket as a property. And then instead of simply calling it like mySMTPSocket, prefix it with Session :

Session.mySMTPSocket

It should be pretty easy to refactor your present code.[/quote]

Thanks again Michel, but i did it but don’t know how to handle the events for the socket, for example MailSent.

Added property to Session: myMailSocket - Type: SMTPSocket - Public

I understand to call it with Session…

But where i place the code for the finished (or error) events?

Best,

You can create a subclass of the smtp socket that has the event code in it. Then use your subclass as the property instead of the plain smtp socket.

Alternatively, but not necessarily recommended, you can use add handler to “attach” a method of your own creation to the event.

Hang in guys, you forgot the issue that SMTPSocket, like all other sockets, has no idea which Session it belongs to. That means that when the MailSent event fires, you’ll also get a SessionNotAvailableException.

Hmm. That’s interesting. I just realized that I don’t even use the events in my web apps. I just send the email from the session and let it go. Funny I haven’t run into any issues with errors doing this, but maybe it’s because I’m sending through my own servers.

So I guess when you init the socket subclass you should store the session identifier or some other identifier so you know how to log or handle the error appropriately. Maybe I should refactor my code. I’ll probably break it if I do though. :slight_smile:

[quote=336640:@JosMaraTerryJimnez]Added property to Session: myMailSocket - Type: SMTPSocket - Public

I understand to call it with Session…

But where i place the code for the finished (or error) events?[/quote]

See http://developer.xojo.com/addhandler for the event, and
http://documentation.xojo.com/index.php/WebSessionContext if you need access to the session from within that event.

Hello

Not success up to now.

I added a new Class (MailSocket) to the project and set its super to SMTPSocket. Then added it the event MailSent and the code to clear the forms

Then in Session added a Property myMailSocket and its type to MailSocket

In Session Open:
Dim myMailSocket As MailSocket

Then in the send button, when set up the socket, the first use of Session.myMailSocket stops with NilObjectException:

Session.myMailSocket.Address = “mail…”

Don’t understand why this.

Any ideas/recommendations?

Thanks

Dim myMailSocket As New MailSocket

Thanks Eli, but the same with that, i tried before but forgot include in my previous reply.

[quote=336651:@Kevin Windham]Hmm. That’s interesting. I just realized that I don’t even use the events in my web apps. I just send the email from the session and let it go. Funny I haven’t run into any issues with errors doing this, but maybe it’s because I’m sending through my own servers.

So I guess when you init the socket subclass you should store the session identifier or some other identifier so you know how to log or handle the error appropriately. Maybe I should refactor my code. I’ll probably break it if I do though. :-)[/quote]

Here’s a Session method I use to set up Session.MailSocket1, a Session property:

Dim s As New MailSocket s.Session = App.SessionWithIdentifier(Self.Identifier) Self.MailSocket1 = s AddHandler Self.MailSocket1.ConnectionEstablished, AddressOf Self.MailSocket1_ConnectionEstablished AddHandler Self.MailSocket1.Error, AddressOf Self.MailSocket1_Error AddHandler Self.MailSocket1.MailSent, AddressOf Self.MailSocket1_MailSent AddHandler Self.MailSocket1.ServerError, AddressOf Self.MailSocket1_ServerError

[quote=336672:@JosMaraTerryJimnez]Hello

Not success up to now.

I added a new Class (MailSocket) to the project and set its super to SMTPSocket. Then added it the event MailSent and the code to clear the forms

Then in Session added a Property myMailSocket and its type to MailSocket

In Session Open:
Dim myMailSocket As MailSocket

Then in the send button, when set up the socket, the first use of Session.myMailSocket stops with NilObjectException:

Session.myMailSocket.Address = “mail…”

Don’t understand why this.

Any ideas/recommendations?

Thanks[/quote]

Perhaps you are not using the New keyword in both these places:

Dim myMailSocket As New MailSocket Dim myEmailMessage As New EmailMessage

In the first case you get a Nil Object Exception because the socket doesn’t exist if you don’t use the New keyword, and in the latter case you get a Nil Object Exception because the email message doesn’t exist if you don’t use the New keyword.

If it is sent fast enough, you may just be getting lucky. Just keep in mind that this won’t hold true for every email server you encounter in the future. [quote=336651:@Kevin Windham]So I guess when you init the socket subclass you should store the session identifier or some other identifier so you know how to log or handle the error appropriately. Maybe I should refactor my code. I’ll probably break it if I do though. :-)[/quote]
Just subclass SMTPSocket, put your identifier in there and us your new socket instead of SMTPSocket.

[quote=336672:@JosMaraTerryJimnez]in Session added a Property myMailSocket and its type to MailSocket

In Session Open:
Dim myMailSocket As MailSocket[/quote]
Do not DIM the variable. That creates a new, local variable with the same name as the session property. The local version gets used in your Open code, leaving the property nil. Instead, just use the property

// in Session Open:
myMailSocket = New MailSocket

Also, clear the form in the code that sends the mail, not in the mailsocket. That way, you don’t have to worry about session context, etc.

// load myMailSocket here
myMailSocket.SendMail
// clear the forms here, you no longer need the values

Hello Tim,

Dim myMailSocket As MailSocket

In Session.Open solves the problem to use the Socket in Session

If I clear fields from the Button Action, it works, but i can’t control that the mail was sent sucessfully or not (I show a MsgBox in the MailSent event (after cleaning fields) or an Error if some happens.)

I’ve write an example from scratch that demonstrates this problem. Just set your SMTP account values in the App Constrants and try. It’s here: The download password is Xojo

In the example the line in Session.Open contains Dim because i uploaded it before read your post and can’t upload again at this moment.

If someone can resolve the problem (and use the events), please share :slight_smile:

Thanks all again.

No, no, no. If you dim, you don’t use the property. Then the reason why you get a nil exception is because myMailSocket exists only in Session.Open !

Admitting myMailSocket is a property of Session, all you got to do is

myMailSocket = New myMailSocket

It is bit discouraging. I posted very precisely the same 2 days ago. Seems you have not read, or understood what I was trying to explain. If you don’t take into account what I and Tim Hare are trying to tell you, you will never get anywhere.

[quote=336775:@Michel Bujardet]No, no, no. If you dim, you don’t use the property. Then the reason why you get a nil exception is because myMailSocket exists only in Session.Open !

Admitting myMailSocket is a property of Session, all you got to do is

myMailSocket = New myMailSocket

It is bit discouraging. I posted very precisely the same 2 days ago. Seems you have not read, or understood what I was trying to explain. If you don’t take into account what I and Tim Hare are trying to tell you, you will never get anywhere.[/quote]

Hello Michel,

Thanks, perhaps i don’t understand, but if i do that in Session.Open (in the project i uploaded, where the property is SMailSocket):

SMailSocket = New SMailSocket

i get an error at compile time:

Expected a type name but found property Session.Session.SMailSocket instead SMailSocket = New SMailSocket

You’re right, i’m completly lost!.

Thanks again.

You said above you had created a class. Actually no need. Here is what you do :

SMailSocket = New SMTPSocket

For the record, here is my post from 2 days ago, the third one in this thread :


Yes, add the SMTPSocket as a property.

mySMTPSocket as SMTPSocket

Initialize it in Session Open as

mySMTPSocket = New SMTPSocket

And then instead of simply calling it like mySMTPSocket, prefix it with Session :

Session.mySMTPSocket

It should be pretty easy to refactor your present code.