[v4] How to call back a function with request?


#1

Hello there,

For my Adonis 4.0 project, I need to create a contact us feature.

First, I created a contact controller with the route leading to it:

'use strict'

const Mail = use('Mail')

class ContactController {
    index ({view}) {
        return view.render('contact') 
    }

    async send ( {view, request, session} ) {
        const data = request.only(['name', 'lastname', 'email', 'message'])

        await Mail.send('emails.welcome', [], (message) => {
          message
            .to('foo@bar.com')
            .from('<from-email>')
            .subject('Welcome to yardstick')
        })
    }
}

module.exports = ContactController
Route.get('contact', 'ContactController.index')
Route.post('send', 'ContactController.send').validator('SendContact')

As you can see I also made a SendContact validator:

'use strict'

class SendContact {
  get rules () {
    return {
      email: 'required|email',
      message: 'required'
    }
  }
}

module.exports = SendContact

Then, I created a view to make it beautiful:

<form role="form" id="contact-form" method="post" action="send">
	{{ csrfField() }}
	<div class="form-group label-floating {{ elIf('has-error', getErrorFor('email'), hasErrorFor('email')) }}">
		<input type="email" name="email" class="form-control" value="{{ old('email', '')}}"/>
	</div>
	<div class="form-group label-floating {{ elIf('has-error', getErrorFor('message'), hasErrorFor('message')) }}">
		<textarea name="message" class="form-control" id="message" rows="6">{{ old('message', '')}}</textarea>
	</div>

	<button type="submit" class="btn btn-primary pull-right">Go</button>

	@if(sent)
		You message has been sent
	@endif
</form>

So as you can see, when the user submit the contact form:
First it uses this route Route.post('send', 'ContactController.send').validator('SendContact').
If the validation fails, it calls back the index function with the old values entered by the user.
If the validation succeed, it calls the send function of the ContactController, it sends the email and then it calls the index function of the ContactController still with the old values entered by the user (not what I want).

What I’d like to do is:

  • getting the return from the Mail.send function to see if everything worked fine, is that the right thing to do? If it is what parameter should I check? I get something like this:
{ 
  accepted: [ 'foo@gmail.com' ],
  rejected: [],
  envelopeTime: 236,
  messageTime: 585,
  messageSize: 353,
  response: '250 2.0.0 OK 1509381553 u52sm22124683wrb.68 - gsmtp',
  envelope: { from: '', to: [ 'foo@gmail.com' ] },
  messageId: '<61588f01-fdd6-d2b1-cf72-9aee756e68b7@DESKTOP-FDJSCT4>'
}
  • if it worked fine, go back to the index function with all fields clean (no old) and a parameter like sent = true, so I can print a message telling the user his email was sent
  • if it didn’t work, go back to the index function with the old values entered by the user and a parameter telling that things went wrong

First of all, is it the right way to do things? It is just a classic contact us feature.
If it is, does someone out there know the right way to do this? I’m pretty sure I don’t need to add much code its just that I don’t know how to call the index function from the send function with a parameter.

Cheers,


#2

I don’t see anything wrong with your code and yes you can feel free to see that the length of accepted field is same as the number of recipients you are sending email to.

Example

const mailPacket = await Mail.send('.....')

if (mailPacket.accepted.length === 1) {
  // email sent
}

#3

In your ContactController.send method.
You forget to redirect your user to a page, this is way your page isn’t actualizing in your browser.

You must want to do response.redirect('back').


#4

Thank you for your help guys.

Just one more thing @romain.lanz, can I send a variable with de redirect? I check this doc http://dev.adonisjs.com/docs/4.0/response#_redirects but when I use true I only get this in url contact?null.

I just want to send a param and be able to check it in my index function to send it to the view.

Sorry for all the noob questions, I’m both new to node and adonis.


#5

Use flash message for that http://dev.adonisjs.com/docs/4.0/sessions#_flash_messages


#6

That’s what I was looking for, thank you!