JavaScript to breakup date of birth for doing an age calculation | XM Community

JavaScript to breakup date of birth for doing an age calculation


Userlevel 7
Badge +6
I am trying to record age at the time of taking the survey, using a an embedded data (Date of birth) in the format YYY-MM-dd. Because date of birth is in 1 embedded field, and not 3 (year of birth, month of birth, day of birth) I can't do an age calculation in survey flow (which is fine as the logic for this is a bit messy and I have a lot of surveys I'd need to add this to).

I imagine javascript code could be written that will calculate the age based on the date if birth field I have, but I am not sure how to write it. Can anyone help?

28 replies

Userlevel 4
Badge +3
Yeah! With Javascripts `Date()` object, you can do a few different things.
I would honestly reach out for a library that could calculate the dates: Moment.JS is the best for that, in my opinion.

Here is a link on how to include it in your Qualtrics project via CDN!
http://momentjs.com/docs/

It allows you to get the absolute difference between two dates as documented here: http://momentjs.com/docs/#/displaying/difference/

Then, you can get the duration between their birthdate and the current date, and break that into years, months, days, and even seconds if you're adventurous.

If the library is too large, or you want to do it Vanilla, there are a few functions out there that others have coded that can get you the absolute difference between a birthday and the current date, but it gets tricky.
Userlevel 4
Badge +3
And as always! If you want more detailed information, I'm glad to code something up for ya!
Userlevel 7
Badge +7
I'd highly suggest integrating Moment.js to handle this. The relative time setup can get you what you are looking for.
Userlevel 7
Badge +6
@Michael_Campbell_RedPepper & @AnthonyR

I am not as technical as I'd like to be. Would either of you mind walking me through this a bit?
Userlevel 4
Badge +3
No worries! This is an excellent platform to learn on!

I'll show you how to get the absolute difference between two dates in months, and I think that should get you started.

In your survey, include this script. You can include it globally in your survey, but sometimes, if a script is only needed for one block of my survey, I'll just throw it into the text of the question. Some might not say that's a 'best practice', but it helps me keep everything separate. And if I delete that block, I'll delete that reference to the script along with it. While editing the description, you can edit the HTML, and then throw this in there:

`<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.21.0/moment.min.js"></script>`. This is the source code for Moment.js. That `min.js` at the end means its minified - it's been run through a program that chops it up into the smallest possible space, switching names for letters, and such. I mention that, because if ever you use 3rd Party Javascript libraries elsewhere, you'll want to use the Minified version. It speeds up the download, and optimizes your customer's experience!

Then there is this code right here:
```
<script>
const monthsSinceBirth = moment(new Date()).diff(moment([2013, 9, 31]), 'months', true);
console.log(monthsSinceBirth);
</script>
```

Moment has a constructor that takes a Date in a few different ways, and I'm showing you two of my favorite - an actual Javascript Date Object, and then an array of the year, month, and then day of month. There are a few other ways to do it, but those are the ones I try to use exclusively.

Moment has a function called `diff()`. It takes three parameters: a moment object (`moment([2013, 9, 31])`), a unit of measure (`months`), and a boolean to ask if you want decimals (`true` will get you those decimals). Try swapping it out with `seconds` and see what happens!

`monthsSinceBirth` may not be the format you want the display to be in, so you'll have to divide it by 12 to get the years since birth.

You can get and set Embedded Data Fields with the following code:
`Qualtrics.SurveyEngine.setEmbeddedData('FIELD', value);`
`Qualtrics.SurveyEngine.getEmbeddedData('FIELD');`

If you need any more information, let me know - but that should get you started.
Userlevel 4
Badge +3
@Akdashboard , were you able to get that to work? I can help you out if you still need it 🙂
Userlevel 7
Badge +6
> @Michael_Campbell_RedPepper said:
> @Akdashboard , were you able to get that to work? I can help you out if you still need it :)

That would be great! I haven't yet been able to figure out where to put everything.
Userlevel 4
Badge +3
@Akdashboard, what part in particular are you still trying to work out?
Userlevel 7
Badge +6
I get that I put this script in the header of the survey.

> `<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.21.0/moment.min.js"></script>`.
>
However, what do I do with this?

> Then there is this code right here:
> ```
> <script>
> const monthsSinceBirth = moment(new Date()).diff(moment([2013, 9, 31]), 'months', true);
> console.log(monthsSinceBirth);
> </script>
> ```

>


Then I assume I put this part in the question JS and create a new embedded data field in the survey flow.

> You can get and set Embedded Data Fields with the following code:
> `Qualtrics.SurveyEngine.setEmbeddedData('FIELD', value);`
> `Qualtrics.SurveyEngine.getEmbeddedData('FIELD');`
>
> If you need any more information, let me know - but that should get you started.

Part of my nervousness is that I can't easily test if this worked correctly and I don't have anyone around me who is technical enough to provide a second set of eyes.
Userlevel 4
Badge +3
For sure! I would do this on the first block. You can, in the menu bar on the right add Javascript, do this in the 'addOnload' function. If you have the date as an Embedded Data Field, then do this:

`const BIRTHDAY= Qualtrics.SurveyEngine.getEmbeddedData('BIRTHDAY');`
`const monthsSinceBirth = moment(new Date()).diff(moment(BIRTHDAY), 'months', true);`
`const yearsSinceBirth = (int) monthsSinceBirth / 12;`
`const monthsSinceLastBirthday = (int) monthsSinceBirth % 12;`
`Qualtrics.SurveyEngine.setEmbeddedData('YEARS_OLD', yearsSinceBirth );`

You probably don't need `monthsSinceLastBirthday`, but you could use it to see if you want to round up or down. And then, you can pipe that into one of your questions!! (note, I haven't tested this code, so it may be imperfect. I'm just not in a place of my schedule where I can do that, but can in a few hours if you need it!)

The benefit of doing this code in the `addOnload` lifecycle method is so you can use the results of it in the `addOnReady` function. It runs after the `addOnload`, so you can know that if the value was calculated correctly, it will be accessible to your program!

My word of advice is to be using `console.log('this will print!')` at every opportunity in the process. If you're in Chrome, you can hit CTRL+Shift+I, and then navigate to the console, and it will print whatever is between the parenthesis! You may already know that, but I can't stress it enough. If it prints `undefined`, then that means, well, the variable wasn't assigned anything, which means there was an error somewhere up the line.

Let me know how that goes!
Userlevel 7
Badge +6
@Michael_Campbell_RedPepper

Really appreciate your help. Admittedly I need more hand holding :neutral:, but I won't make you walk me through it. I have only done a handful of coding things in Qualtrics and I don't have a good fundamental knowledge base of JavaScript, so a lot of what you said only 'sort of' makes sense. Thanks again though.
Userlevel 7
Badge +6
Someone from Qualtrics was able to provide me some simple JS that I could use to breakout the date of birth field into 3 other fields (year of birth, month of birth, and day of birth). I can then do some math operations to generate age at the time the survey was taken.

I am running into an issue where year of birth, month of birth, and day of birth aren't posting as embedded data. Can anyone look at what I have and tell me what I am doing wrong?
Userlevel 4
Badge +3
Yeah, lemme take a look. I'm glad they were able to help!
Userlevel 4
Badge +3
Okay, initially, I see that you're not using the lifetime cycle functions - I recommend using those. Your code will work without them (I'm 99% sure), but its best to use them. At what point are you setting your Embedded Data Field for `DATE_OF_BIRTH`?
Userlevel 4
Badge +3
Fixed it! Here is my code:

```
Qualtrics.SurveyEngine.addOnload(function()
{
/*Place your JavaScript here to run when the page loads*/
Qualtrics.SurveyEngine.setEmbeddedData('DATE_OF_BIRTH', '1985-08-14');
const birthday = Qualtrics.SurveyEngine.getEmbeddedData('DATE_OF_BIRTH');

birthdayArr = birthday.split("-")
Qualtrics.SurveyEngine.setEmbeddedData("Year_of_Birth",birthdayArr[0])
Qualtrics.SurveyEngine.setEmbeddedData("Month_of_Birth",birthdayArr[1])
Qualtrics.SurveyEngine.setEmbeddedData("Day_of_Birth",birthdayArr[2])
});

Qualtrics.SurveyEngine.addOnReady(function()
{
/*Place your JavaScript here to run when the page is fully displayed*/


console.log(Qualtrics.SurveyEngine.getEmbeddedData('Year_of_Birth'));
console.log(Qualtrics.SurveyEngine.getEmbeddedData('Month_of_Birth'));
console.log(Qualtrics.SurveyEngine.getEmbeddedData('Day_of_Birth'));

});

Qualtrics.SurveyEngine.addOnUnload(function()
{
/*Place your JavaScript here to run when the page is unloaded*/

});
```
Userlevel 7
Badge +6
@Michael_Campbell_RedPepper Awesome! Thank you so much for your help.

Looks like my original code didn't have a .get statement in order to pull in date of birth (doh!).

I see the .get and .set statements, but what is this doing?
console.log(Qualtrics.SurveyEngine.getEmbeddedData('Year_of_Birth'));
console.log(Qualtrics.SurveyEngine.getEmbeddedData('Month_of_Birth'));
console.log(Qualtrics.SurveyEngine.getEmbeddedData('Day_of_Birth'));
Userlevel 7
Badge +6
Also, what is lifetime cycle?
Userlevel 4
Badge +3
Oh! Awesome!

And yeah! Sorry, let me explain - I thought that I had talked to you about it previously, but I realize now that was a different person.

Qualtrics Surveys, as with many other applications (Mobile Applications use this a ton) have a Lifecycle process. The app is loaded (without being displayed), then it is displayed, and the user interacts with it, and then it's offloaded (once the user navigates away or the window is closed).

You can put certain functionality in those functions to synchronize your actions with those in the survey. There are a lot of important concepts on this that are beyond the scope of this discussion, but there are a few that are worth mentioning. Here are some best practices:

In the `addOnload`, it's best to load data that will be used in the survey itself. Getting Embedded Data Fields, setting variables that will be presented, etc. I'm not sure if Qualtrics does this, but in other platforms, it's wise to not put _too much_ processing in this part of the survey. Doing so will cause the application to load slowly. Any REST API Calls or saving/setting data that isn't required as part of the user experience should take place later in the process.

In the `addOnReady`, the page is presented to the user (already), and they can be or are already interacting with the survey. Here, you can do some heavier lifting, but if you're trying to reference a JS variable in your survey (via piped text, etc), it could very easily not be set, and so you'll get a blank. That has happened to me before!

This is an older document, and so there may be missing/inaccurate information, but it talks a bit more about other Lifecycle methods!

https://s.qualtrics.com/WRAPI/QuestionAPI/classes/Qualtrics%20JavaScript%20Question%20API.html
Userlevel 4
Badge +3
Oh! And
```
console.log(Qualtrics.SurveyEngine.getEmbeddedData('Year_of_Birth'));
console.log(Qualtrics.SurveyEngine.getEmbeddedData('Month_of_Birth'));
console.log(Qualtrics.SurveyEngine.getEmbeddedData('Day_of_Birth'));
```

Is just testing to make sure it works! I `console.log()` a ton in testing as an ad hoc way to make sure all my data is being set correctly!
Userlevel 7
Badge +6
@Michael_Campbell_RedPepper - You are just flat out awesome. Very much appreciate your help with this.
Userlevel 4
Badge +3
@Akdashboard Of course! I enjoy helping 🙂
> @Michael_Campbell_RedPepper said:
> No worries! This is an excellent platform to learn on!
>
> I'll show you how to get the absolute difference between two dates in months, and I think that should get you started.
>
> In your survey, include this script. You can include it globally in your survey, but sometimes, if a script is only needed for one block of my survey, I'll just throw it into the text of the question. Some might not say that's a 'best practice', but it helps me keep everything separate. And if I delete that block, I'll delete that reference to the script along with it. While editing the description, you can edit the HTML, and then throw this in there:
>
> `<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.21.0/moment.min.js"></script>`. This is the source code for Moment.js. That `min.js` at the end means its minified - it's been run through a program that chops it up into the smallest possible space, switching names for letters, and such. I mention that, because if ever you use 3rd Party Javascript libraries elsewhere, you'll want to use the Minified version. It speeds up the download, and optimizes your customer's experience!
>
> Then there is this code right here:
> ```
> <script>
> const monthsSinceBirth = moment(new Date()).diff(moment([2013, 9, 31]), 'months', true);
> console.log(monthsSinceBirth);
> </script>
> ```
>
> Moment has a constructor that takes a Date in a few different ways, and I'm showing you two of my favorite - an actual Javascript Date Object, and then an array of the year, month, and then day of month. There are a few other ways to do it, but those are the ones I try to use exclusively.
>
> Moment has a function called `diff()`. It takes three parameters: a moment object (`moment([2013, 9, 31])`), a unit of measure (`months`), and a boolean to ask if you want decimals (`true` will get you those decimals). Try swapping it out with `seconds` and see what happens!
>
> `monthsSinceBirth` may not be the format you want the display to be in, so you'll have to divide it by 12 to get the years since birth.
>
> You can get and set Embedded Data Fields with the following code:
> `Qualtrics.SurveyEngine.setEmbeddedData('FIELD', value);`
> `Qualtrics.SurveyEngine.getEmbeddedData('FIELD');`
>
> If you need any more information, let me know - but that should get you started.

Hi! Does this also work in the Qualtrics offline app?
Badge +1

A few Qs about the survey flow...
in the survey flow, for the new embedded fields you are creating via the javascript, where do you put embedded data block - before or after the question/block that has the JS? If that matters?
Also, embedded data field in survey flow defaults to "value will be set from panel or URL" Do i leave as is? If not, if i need to "set value now", what do i choose from the drop-down?

Userlevel 7
Badge +6

Hi Christin
1 - It doesn't matter where you put the embedded data element in your survey flow, unless you want to use the data values in your survey (piped text, logic, etc.). In which case (and as a general best practice), put it at the vey top of your survey flow.
2 - Yes, leave the embedded data fields "empty" (i.e., when they say "value will be set from panel or URL"). Otherwise you would be setting the data value to whatever you enter there. For example age = "values from panel or URL" will be filled by the program, but age = 20 will hard set the age to 20.

Badge +1

Thank you so much Akdashboard !

Leave a Reply