Retrieving user input and generating output for another page

Hello,
I’m working on a surgery outcome calculator where a user inputs his age, gender, BMI, and another index on the home page of my site. These inputs would then be manipulated through regression equations I have modeled. The individual would then have his/her predicted outcome on a new page. I am confused about retrieving the numerical values of the user inputs because the .get() method returns a Promise object, which I’m not familiar with. For example, do I simply code:

import wixData from ‘wix-data’;
let var_age = wixData.get(“OutcomeCalculator”, “age”);
let var_gender = wixData.get(“OutcomeCalculator”, “gender”);

//gender was coded so that Male is saved in my database collection as 1 and Female as 0.

The second part of my question is once I run these values through the regression equations, will l be able to show this output on another page. For example if the output was “62% improvement” could I connect my 2nd page to this output.

I appreciate your responses in advance.

Question 1: No. wix-data.get needs a _id as an argument. You will need to build a query. See API doc;
Question 2: Yes. Look at wix-location.

1 Like

Hi Giri,

I built a query but am not sure how to retrieve the numerical value of a particular field so that I can manipulate it. Also referring back to my outcome calculator, could I make an empty field in my collection called “outcome” and then use an after query hook that will update this field as I run the items in my query through the equation? Then I could refer to this field when I want to post the outcome on a new page.

Retrieving is simple. Let´s assume that you assigned the query result to a var called objQueryResult. Let´s also assume that the query result always returns 1 row (=1 person). Query results are 0-based, meaning that the (only) row is row(0) , the next, if any, row(1), etc. Watch out that .totalCount is 1-based. So if .totalCount returns 0, there IS no row. If it returns 1, there is, and you should address it in the query result as row 0!!
With .items you select a row (plus row indicator) and with the dot-notation you retrieve a field value from that particular row, something like:

let numBMI = objQueryResult.items[0].bmi;

Now the var numBMI should hold the value from that row in the db.

On writing a value back to db. Yes, you should take up that “empty” field in your db and then write it back after you have done your calculation. If that really needs to be done in a DB-hook is up to you. DB-hooks are performed always, independent of the application code. When is this useful? Well, for instance if you save to the same collection in two different places, e.g. in your web based application and thru an REST-Api that you want to offer to others.
DB-hooks have the same “problem” as triggers/stored procedures in relational db´s: you don´t see the code. Db-hooks in Wix are relegated to a separate backend file (“data.js”) and if something is done there, you must document this very well in page code. If not, you will forget within half a year, you look at your page code and you cannot find out where it happens. If another developer looks at it, even worse.

So yes, you can do a hook, but if you manipulate the “outcome” in only 1 place, there is no real need. A simple .save() or .update() will do the same trick.
It´s up to you. Hope this helps.

1 Like

Amazing detail. Thanks for all your help, Giri!

Hi Giri,

I’m having some issues with indices. When working with the query, my regression equations seem to be computing the value of inputs that get stored in row2 as opposed to row1. Essentially, they are calculating the outcomes for the previous set of inputs.

Also, am I incorrectly using the update method? The database does not reflect the calculated outcomes.
I have attached a screenshot of my code

There are a couple of things wrong, but before I answer, could you tell me one thing: these calculations, are they made on a page where a user just input the necessary data and then you do these calculations after which you relegate them to a results page, or, do you do these calculations in a batch for many users, not specifically at the moment at which they have filled out the data?

A user will input the necessary data on the home page (shown below), the backend script will perform the calculations, and immediately the user will receive his/her average, best, least, and worst possible outcome on the following results page. In context of the purpose, this calculator is meant to show the post-operation outcome for that specific user.

Got it. I will answer tomorrow. Bit late here now.

3 more questions:
a) do people register first before you do the calculation and if they do, do you envision of having them do just 1 calculation, or several? or
b) do they (anonymously) fill out the data, which you would like to store and do the calculation on? IN this case, storing data would only give you statistical info.
c) that form you showed, do you have that tied to a dataset on the page?

This calculator is purely for the patient to be more informed before he/she would have surgery.

They will not have to register any personal information. They will fill out the form on the home page, which will be stored in the collection where the calculation will be done. The patient will receive only statistical info on the results page. The results page will most likely be as the table shown below.

Yes, the form is tied to a dataset on the page called “OutcomeCalculator dataset”

OK, since it is already tied to a dataset, we are going to use that possibility. I assume you got as far as being able to save an entry to the collection. We forget about the query (for now) and we do this:

  1. if you have your Submit-button set up as a dataset-submit button (you chose a Submit button when designing the form) we are going to detach it from the dataset (click its Setings and bind it to nothing).
    If that does not work, delete the button and add a new , standard, unbound one. Here, we will call it #button1. In the properties panel, add a handler for the onClick event. Wix will than insert an empty piece of code like below and we will add some code (explained later):

export function button1_click ($w, event) {
objSaved = $w(“#myDataset”).save()
.then( (item) => { let strPrimaryKey= item._id; } )
.catch( (err) => { let errMsg = err; } );
}

  1. in the datasets onBeforeSave (called before something is saved) we are going to do the whole calculation , something like this:

$w(“#myDataset”).onBeforeSave( () => {
fnCalculateIndices();
} );

  1. in the function fnCalculateIndices() we do something like this:

export function fnCalculateIndices() {
let numAge = $w(“#inputfieldage”).value;
etc

// And do your magical calculations here.(So we replace the items[0] with input from the form)
}

  1. and we are going to write the results to the row like this
    export function fnCalculateIndices() {
    let numAge = $w(“#inputfieldage”).value;
    etc
    $w(“#myDataset”).setFieldValue(“age”, numAge);

// assuming that the field in the collection is called “age” and we fill it with the value of the var numAge. I put //num in front of the var, so the code reads better and you can distinguish visulally between a db-field and a //var in your code

etc (like BMI, etc)
}
5) now we have done the calculations, these values have been written to the dataset and finally, it will be saved because all was triggered from the .save in the first place.

  1. now we need to show the results on a second page. We are going to use a little trick: we are going to define it as a Dynamic Page. So, we add a new page called “Results” (or whatever) and define it as a Dynamic Page. Wix will ask you a url, and you define the URL as www…/{Id}
    You attach the same collection to the dataset as we just saved.
    On this page, you just put in all the text boxes (the results) you want (text, not user input) and you bind them to the result fields in the collection using the GUI.
    Why do we use a Dynamic Page? Well, when you do, Wix already retrieves the item for you (like we did a couple of days ago with the query) and makes it available programatically and ready to use for interface elements. So we no longer need that query.

  2. now we need one more thing: to get from the input page to this one. Well, we already had this code in the button1.onClick:

export function button1_click ($w, event) {
objSaved = $w(“#myDataset”).save()
.then( (item) => { let strPrimaryKey= item._id; } )
.catch( (err) => { let errMsg = err; } );
}
What we did here was saving the dataset. When you do, Wix returns the whole saved dataset. We catch this and attach it to the var objSaved. Now that one holds all the saved fields. We want to extract the Primary Key from it (that one Wix added while saving, it´s a long string like “0c45fg28…”), which we did with “let strPrimaryKey= item._id;”
Now we use wix-location to go to this Dynamic Page. Remember that at the top of you page code, you should import wix-location like this:

import wixLocation from ‘wix-location’;

and, to put it all together, we add in this function a last line:

wixLocation.to(“/results/”) + strPrimaryKey;

Note that we called the page Results and here we write results. To find the real name of the page, click the page properties and go to SEO. There you will find the real page name for referring to it in code.

  1. think about what you want people to do on that result page. Maybe put a button in there with a caal to action to another page, maybe go back to the home page.

This should be it. I have NOT tested this code, but apart from some glitches, this should work.

Hope this helps.

1 Like

change
wixLocation.to (“/results/”) + strPrimaryKey;

to

wixLocation.to (“/results/” + strPrimaryKey);

Truly amazing, Giri. Thank you. I have one last bit to troubleshoot and that is linking the submit button to the dynamic page. When producing the URL for the dynamic page I included all the fields that I plan on showing (Average3months, Average6months, etc.) The url according to the SEO is:

https://www…/OutcomeCalculator/{Average3months}/{Average6months}/{Average1year}/{Best3months}/{Best6months}/{Best1year}/{Least3months}/{Least6months}/{Least1year}/{Worst3months}/{Worst6months}/{Worst1year}/{ID}

I have entered this into my code but appear to run into a 404 error.

Also just to confirm, I am supposed to link the text boxes on the outcome page to the data collection or data set?

Update. I realized my mistake. It works :slight_smile: