How to use onAfterSave() ?

Hi,
Tried to use onAfterSave() after a dataset.save() in order to display the changes in a table bound to a dataset. But I get an error msg “cannot be used during a save operation”.
After reading the forum, I tried :

async function() {
         await $w("#dataset1").save();
         ...
}

but async function can apparently not be used this way : “parsing error, unexpected token(”
All that in order to refresh a table after an item has been selected and then modified outside of the table. All what I tried before fails (dataset.refresh, table.refresh, updateRow…). The collection is well updated (in preview only, sadly not in live, that’s another issue, I did not get any working solution in the forum).
the code looks like this :

 ...
$w('#dataset1').save();
$w("#dataset1").onAfterSave( () => {
          $w("#dataset1").setFilter(wixData.filter()
            .gt('dateHeure', lowerDate)
            .lt('dateHeure', upperDate)
        )
            .then( (res) => {
            let tableRows = res.items;
            $w('#table1').rows = tableRows;
            })
        .catch( (err) => {
        let errMsg = err;
        console.log('not ok'+errMsg);
        });
})

Hi Francois,

Try adding the onAfterSave from the dataset property sheet and then place the setFilter code in the function block that is created.

ah yes, nice ! did not think of that…

Thank you Anthony !

I am having trouble getting the onAfterSave event at all.

I tried what AnthonyB suggested, and the code generated was

export function dataset1_afterSave ( ) {

which I took out of onReady() and it does nothing

$w ( ‘#dataset1’ ). onAfterSave ( () => {

is INSIDE onReady() and it ALSO does NOTHING.

I’m not totally sure when to use export funtion and when to use $w(

I’m waisting a ton of time on this.

When I put export function INSIDE of onReady() I get the code parsing error:

Modifiers cannot appear here.
Parsing error: ‘import’ and ‘export’ may only appear at the top level

What’s going on?

Code-Skeleton:

Try to do it this way…complete the code…

$w.onready(()=>{
   $w('#myDatasetIDhere').onReady(()=>{
		
   });
	
   $w('#myDatasetIDhere').onAfterSave(()=>{
	
   });

   $w('#mySubmitButtonIDhere').onClick(()=>{
	   $w("#myDataset").setFieldValue("title", "New Title");
	   $w("#myDataset").save();
   });
});

Thanks Code Skeleton, here’s what I have:

$w.onReady(function () {

$w('#dataset1').onAfterSave( () => {
  console.log("onReady onAfterSave()")
})

$w("#button2").onClick( (event) => {

  let toSave = {
    "title": TeamName, 
    "firstname": $w("#input2").value,
    "lastname": $w("#input3").value,
    "email": $w("#input4").value,
    "cell": $w("#input5").value
  };
  
  wixData.save("TeamMembers",toSave)
    .then( (results) =>{
      let item = results;
      $w("#input2").value = "";
      $w("#input3").value = "";
      $w("#input4").value = "";
      $w("#input5").value = "";
      console.log("SAVE SUCCESS-->",item);
    } )
    .catch( (err) =>{
      let error = err;
      console.log("SAVE ERROR-->",error);
    });
});   // BUTTON2 CLICK END

}); // onReady end

I get SAVE SUCCESS, but not “onReady onAfterSave()”

dataset1 is TeamMembers, I get a parsing error if I put in #TeamMembers or TeamMembers

The dataset.onAfterSave() event handler is not being triggered because you are not saving using dataset.save() as @russian-dima showed in his code skeleton. If you use the wix-data API , it will not trigger dataset event handlers.

1 Like

Thanks Yisrael.
Like Yisrael already mentioned, you are mixing Wix-Data & dataset-processes.

Delete the following part…or comment it-out. Why do you need wix-data? You are already connected to a dataset!

wixData.save("TeamMembers",toSave)
.then( (results) =>{
    let item = results;
    $w("#input2").value = "";
    $w("#input3").value = "";
    $w("#input4").value = "";
    $w("#input5").value = "";
    console.log("SAVE SUCCESS-->",item);
} )
.catch( (err) =>{
    let error = err;
    console.log("SAVE ERROR-->",error);
});

And also like Yisrael said → if you want to trigger the onAfterSave-event, then you will needs these two…

$w('#dataset1').setFieldValue("title", "New Title");
$w('#dataset1').save();

…to be more precise, especialy the save()-function…

$w('#dataset1').save();

Since you want to save more than 1 or 2 values, you will have to use…

$w('#dataset1').setFieldValues( {
    "title": TeamName, 
    "firstname": $w("#input2").value,
    "lastname": $w("#input3").value,
    "email": $w("#input4").value,
    "cell": $w("#input5").value
});

Good luck!

1 Like

I appreciate the help, I will try it this way!

1 Like

OK, I used $w(“#dataset1”).save() and this seems to generate an onAfterSave() event,

BUT… my whole point for using the onAfterSave even is to send an email using the data just saved. I had this working at one point, but now all I get is FAILED TO FETCH when it gets to actually sending a TRIGGERED_EMAIL.

Here’s my page code:

import wixLocation from 'wix-location';
import wixCRM from 'wix-crm';
import { triggeredEmails } from 'wix-crm';
import {memory} from 'wix-storage';




$w.onReady(function () {
 let TeamId = memory.getItem("TeamId");
 let TeamName = memory.getItem("TeamName");
 $w("#text63").text = TeamName;

$w('#dataset1').onAfterSave( () => {
  console.log("onReady dataset1.onAfterSave()");
  let TeamName = memory.getItem("TeamName"); 
  let InviteeName = $w("#input2").value + " " + $w("#input3").value;;
    let firstName = $w('#input2').value;
    let lastName = $w('#input3').value;
    let email = $w('#input4').value;
    let phone = $w('#input5').value;
    console.log("SENDING EMAIL"+" mailto:"+email+" TeamName-"+TeamName+" phone="+phone+" InviteeName="+InviteeName);

    let contactInfo = {
      "firstName": firstName,
      "lastName": lastName,
      "emails": [email],
      "phones": [phone],
    };
   console.log("contactInfo set "+contactInfo)
  
      wixCRM.createContact(contactInfo)
      .then( (contactId) => {
            console.log("Contact Created contactId="+contactId);  // THIS MESSAGE SHOWS CORRECTLY
          triggeredEmails.emailContact('Sosgvzd', contactId, {   //SrhtD9P  // Sosgvzd
             
            "variables": {
              "InviteesName": InviteeName,
              "TeamName": TeamName
              }
            })
            .then( () => {
            console.log("Triggered Email SENT");  // THIS MESSAGE NEVER SHOWS, I GET ERROR "FAILED TO FETCH"
            // FOLLOWING CODE IS EXECUTED ON SUCCESS OF EMAIL SEND, I CALL THIS PAGE FROM 2 PLACES, AND IT MUST RETURN ONE OF 2 PLACES BASED ON "from" in memory
 /*         if(memory.getItem("from") == "Create-Team"){
            wixLocation.to("/account/Create-a-Team-3");
            }else{
            wixLocation.to("/account/Edit-Team");
            } */
            })
         } )
        .catch( (err) =>{
            let errorMsg = err;
            console.log("TRIGGERED EMAIL ERROR-->",errorMsg);
          });
    }); // onAfterSave

$w("#button2").onClick( (event) => {

  $w('#dataset1').setFieldValues( {
    "title": TeamName, 
    "firstname": $w("#input2").value,
    "lastname": $w("#input3").value,
    "email": $w("#input4").value,
    "cell": $w("#input5").value
});
  $w('#dataset1').save();

});   // BUTTON2 CLICK END

});  // ONREADY END

I’m stuck at FAILED TO FETCH any comments?

Question: Why you are not trying to use the → CONSOLE to debug your issue on your own?

The CONSOLE should be normaly your → BEST-FRIEND ← when you have a code-issue. You can analyse your code step by step (line after line) and find this way the exact position, which causes your ERROR.

Place some console.logs on important parts in your code → run your code → and inspect the → outputs.

You don’t know how to use the → CONSOLE?

  1. In the preview-mode of your Wix-Editor you will find a buil-in-console on the very bottom of your screen.
  2. Press F12 if you are using → GOODLE.-CHROME or Microsoft-EDGE-browser + navigate to console-section.

Example: You want to know if all your values are valid and ok ? → Console.log it!

let TeamName=memory.getItem("TeamName"); console.log(TeamName);
let InviteeName=$w("#input2").value+" "+$w("#input3").value; console.log(InviteeName);
let firstName=$w('#input2').value; console.log(firstName);
let lastName=$w('#input3').value; console.log(lastName);
let email=$w('#input4').value; console.log(email);
let phone=$w('#input5').value; console.log(phone);

First find the right code-part, which causes the issue in your running (not running) code.

I found my answer, the code actually wasn’t the problem. It was the data in my CONTACTS table the caused the FAILED TO FETCH problem.

I cleared the CONTACTS table and it works fine, though I’m now using:

contacts.appendOrCreateContact(contactInfo)

Instead of contacts.save because I don’t want a duplicate of an existing contact save error.

I wished someone could have interpreted the FAILED TO FETCH error. In case anyone gets a FAILED TO FETCH when trying to send a TRIGGERED EMAIL, clear your CONTACTS and any RELATED tables you are using. I’m reminded that your DATA is the part of the CODE-DATA you need to check also when getting errors.

BTW… I DO KNOW how to use console.log() … none of my variables were wrong, I had been up and down that already. Velo-Ninja, a little more tact, and a little less condescension would have been appreciated with your comment.

Glad you got this worked out. However, just for my own curiosity, what do you mean by “CONTACTS table”? What table? Where? How is it being used, and how was it causing a problem?

Thanks Yisrael for all your help.

I used import { contacts } from ‘wix-crm’ ;

The page has a simple form I made with email, FirstName, LastName and CellNumber. I want to send an email when the form is submitted, I use TriggeredEmail so a CONTACT is required. I found examples for this, but had trouble. The table is not CONTACTS but CONTACT, under databases. I assume it existed by default or somehow importing wix-crm created it? Here’s my code that executes when you submit the form.



import wixLocation from 'wix-location';
import wixCRM from 'wix-crm';
import { triggeredEmails } from 'wix-crm';
import {memory} from 'wix-storage';
import { contacts } from 'wix-crm';
$w.onReady(function () {
 let TeamId = memory.getItem("TeamId");
 let TeamName = memory.getItem("TeamName");
 $w("#text63").text = TeamName;
 
$w('#dataset1').onAfterSave( () => {
  console.log("onReady dataset1.onAfterSave()");
  let TeamName = memory.getItem("TeamName"); 
  let InviteeName = $w("#input2").value + " " + $w("#input3").value;;
    let firstName = $w('#input2').value;
    let lastName = $w('#input3').value;
    let email = $w('#input4').value;
    let phone = $w('#input5').value;
    console.log("SENDING EMAIL"+" mailto:"+email+" TeamName-"+TeamName+" phone="+phone+" InviteeName="+InviteeName);
    
let contactInfo = {
  name: {
    first: $w('#input2').value,
    last: $w('#input3').value
  },
  emails: [
    {
      email: $w('#input4').value,
    }
  ],
  phones: [
    {
      tag: 'MOBILE',
      countryCode: 'US',
      phone: $w('#input5').value,
      primary: true
    }
  ]
};
   console.log("contactInfo set "+contactInfo)
  // if email exists already append if not creat it
    contacts.appendOrCreateContact(contactInfo)
  .then( (result) => {
            console.log("Contact Created contactId="+result.contactId);  // THIS MESSAGE SHOWS CORRECTLY
          // I think TriggeredEmails is a wrapper for wixCRM ?
          //triggeredEmails.emailContact('Sosgvzd', contactId, {   //SrhtD9P  // Sosgvzd
          wixCRM.emailContact('Sosgvzd', result.contactId, {   //SrhtD9P  // Sosgvzd  SsLTwsg
             
            "variables": {
              "member":"a HelpGrandma member",
              "InviteesName": InviteeName,
              "TeamName": TeamName
              }
            })
            .then( () => {
            console.log("Triggered Email SENT");  // BEFORE, THIS MESSAGE NEVER SHOWS, I GOT ERROR "FAILED TO FETCH" -- NOW FIXED
            $w("#text63").text = "Email SENT";
            // FOLLOWING CODE IS EXECUTED ON SUCCESS OF EMAIL SEND, I CALL THIS PAGE FROM 2 PLACES, AND IT MUST RETURN ONE OF 2 PLACES BASED ON "from" in memory
          if(memory.getItem("from") == "Create-Team"){
            //import wixLocation from 'wix-location';
            wixLocation.to("/account/Create-a-Team-3");
            }else{
            wixLocation.to("/account/Edit-Team");
            } 
            }) 
         } )
        .catch( (err) =>{
            let errorMsg = err;
            console.log("TRIGGERED EMAIL ERROR-->",errorMsg);
          });
    }); // onAfterSave

$w("#button2").onClick( (event) => {
// first save data, then onAfterSave() event will handle the rest
  $w('#dataset1').setFieldValues( {
    "title": TeamName, 
    "firstname": $w("#input2").value,
    "lastname": $w("#input3").value,
    "email": $w("#input4").value,
    "cell": $w("#input5").value
});
  $w('#dataset1').save();

});   // BUTTON2 CLICK END

});  // ONREADY END

I have another problem Yisrael…

I need to tag my Triggered Email with some data, specifically the MemberID and TeamName from the Member who sends this INVITATION email. It’s an invitation to be part of a TEAM.

When the email recipient clicks on the button in the email, I want to send this data back to the Members page like this (or somehow)

…/account/TeamAccept/${MemberID},${TeamName}

and I want to use this to lookup the proper Team to REGISTER the Invitee to the TEAM. I figure just a regular Query of the TEAMMEMBERS table to do this.

My problem is how to make the URL hold the data or send it back from the email. then what code EXTRACTS it from the URL? Do I need a RESTAPI? or use HTTP get and put? or JSON?

Regarding the special link on the button in the triggered email…

Not sure if this can be done - at least I’m not aware of this option. You might want to check with Wix Customer Care as they’re much smarter than I am.

You might consider sending your own emails. It might be a bit more work, but it provides endless possibilities for customization. If you’re interested, see these two examples:

As far as your site receiving the reply when the button/link is clicked in the email, you’ll need to expose an API in your site using HTTP functions . See these two examples for details: