How to add viewedPodcasts key to Member JSON without extra data nesting in Webflow? Answered

Post author
Alastair Budge

Wondering if someone can help me out with adding Member JSON. I (and ChatGPT) can’t figure this one out…
I am trying to update user JSON so that there is a key called viewedPodcasts which is updated with the unique IDs of Webflow CMS items.
Here is the script I have:

memberstack.getCurrentMember().then(async ({ data: member }) => {
// If the member is logged in
if (member) {
// Get current member's JSON
let memberJson = await memberstack.getMemberJSON(); // Initialize 'viewedPodcasts' array if it doesn't exist
if (!memberJson.viewedPodcasts) {
memberJson.viewedPodcasts = [];
} // Check if the CMS item has already been viewed
const cmsItemId = "{{wf {"path":"episode-number","type":"Number"\} }}"; // Replace with actual ID
if (!memberJson.viewedPodcasts.includes(cmsItemId)) {
// Add CMS Item ID to 'viewedPodcasts' array
memberJson.viewedPodcasts.push(cmsItemId);
} // Update member's JSON
await memberstack.updateMemberJSON({json: memberJson}); // Log the updated JSON data
console.log(await memberstack.getMemberJSON());
}
});

It is adding the JSON, but it keeps nesting it within additional “data” keys, so the JSON ends up looking like this:

{
"data": {
"data": {
"data": {
"data": {
"viewedPodcasts": [
"71ksac0d83"
]
},
"viewedPodcasts": [
"71ccxksac0d83"
]
},
"viewedPodcasts": [
"402"
]
},
"viewedPodcasts": [
"400"
]
}
}

Can anyone help me adjust it? thanks.

Comments

2 comments

  • Comment author
    John Matias

    Hey Alastair Budge I'm not sure exactly what the error is on your specific code. But I feel like you are close to having this solved.

    I'm providing you the script I was able to pull together (also with ChatGPT) and it is working well for me. I'm thinking maybe you can look through it and compare to get some ideas.

    <!-- Memberstack Member Videos -->
    
    <script>
    const memberstack = window.$memberstackDom;
    const expirationDateElement = document.getElementById("expirationDate");
    const btnPlay1 = document.getElementById("btnPlay1");
    const btnPlay2 = document.getElementById("btnPlay2");
    
    memberstack.getMemberJSON().then(async ({ data: memberJSON }) => {
      // Initialize vodVideos as an array
      let vodVideos;
      // Declare newMemberJSON and assign it the value of memberJSON
      let newMemberJSON = memberJSON || {};
    
      // If the newMemberJSON object does not have a property called "vodVideos", add it
      if (!newMemberJSON.hasOwnProperty("vodVideos")) {
        newMemberJSON["vodVideos"] = [];
      }
      // Assign vodVideos the value of the "vodVideos" property of newMemberJSON
      vodVideos = newMemberJSON["vodVideos"];
      
      const videoID = "{{wf {&quot;path&quot;:&quot;video-ecommerce-sku&quot;,&quot;type&quot;:&quot;PlainText&quot;\} }}";
      const index = vodVideos.findIndex(video => video.videoID === videoID);
      if (index !== -1 && vodVideos[index].hasOwnProperty("expirationDate")) {
        const expirationDate = new Date(vodVideos[index].expirationDate);
        const formattedExpirationDate = expirationDate.toLocaleDateString("en-US", {
          month: "long",
          day: "numeric",
          year: "numeric"
        });
        if (expirationDateElement) { expirationDateElement.innerHTML = "Rental expires on: " + formattedExpirationDate; }
       
       // Check to see if the video rental has expired and hide play buttons if true
    if(new Date() > expirationDate) {
          if (btnPlay1) btnPlay1.style.display = "none";
          if (btnPlay2) btnPlay2.style.display = "none";
          if (expirationDateElement) { expirationDateElement.innerHTML = "Your rental has expired."; }
          }
        } else {
        if (expirationDateElement) { expirationDateElement.innerHTML = "Your rental expires in one year."; }
      }
    
       // Add event listener for the "btnPlay1" button
      document.getElementById("btnPlay1").addEventListener("click", async function() {
        // Get the value of the videoID variable
        const videoID = "{{wf {&quot;path&quot;:&quot;video-ecommerce-sku&quot;,&quot;type&quot;:&quot;PlainText&quot;\} }}";
    
        // Find the index of the videoID in the vodVideos array
        const index = vodVideos.findIndex(video => video.videoID === videoID);
        // If the videoID is already in the array, increment the views count for that video
        if (index !== -1) {
          vodVideos[index].views++;
        } else {
          // If the videoID is not in the list, add it with a views count of 1
          const currentDate = new Date();
          const expirationDate = new Date();
          expirationDate.setDate(currentDate.getDate() + 365);
          vodVideos.push({
            videoID: videoID,
            views: 1,
            expirationDate: expirationDate
          });
          const formattedExpirationDate = expirationDate.toLocaleDateString("en-US", {
        		month: "long",
        		day: "numeric",
        		year: "numeric"
          });
          if (expirationDateElement) { expirationDateElement.innerHTML = "Rental expires on: " + formattedExpirationDate; }
        }
              
        // Update the user's data in MemberStack with the updated newMemberJSON object
        await memberstack.updateMemberJSON({
          json: newMemberJSON
        });
        
        // Hide the element with the id "vodOverlay"
        document.getElementById("vodOverlay1").style.display = "none";
      });
    
      // Add event listener for the "btnPlay2" button
      if(btnPlay2) { btnPlay2.addEventListener("click", async function() {
        // Get the value of the videoID variable
        const videoID = "{{wf {&quot;path&quot;:&quot;video-ecommerce-sku&quot;,&quot;type&quot;:&quot;PlainText&quot;\} }}";
    
        // Find the index of the videoID in the vodVideos array
        const index = vodVideos.findIndex(video => video.videoID === videoID);
        // If the videoID is already in the array, increment the views count for that video
        if (index !== -1) {
          vodVideos[index].views++;
        } else {
          const currentDate = new Date();
          const expirationDate = new Date();
          expirationDate.setDate(currentDate.getDate() + 365);
          vodVideos.push({
            videoID: videoID,
            views: 1,
            expirationDate: expirationDate
          });
          const formattedExpirationDate = expirationDate.toLocaleDateString("en-US", {
        		month: "long",
        		day: "numeric",
        		year: "numeric"
          });
          if (expirationDateElement) { expirationDateElement.innerHTML = "Rental expires on: " + formattedExpirationDate; }
        }
    
        // Update the user's data in MemberStack with the updated newMemberJSON object
        await memberstack.updateMemberJSON({
          json: newMemberJSON
        });
    
        // Hide the element with the id "vodOverlay"
        document.getElementById("vodOverlay2").style.display = "none";
      });
      }
    });
    </script>
    Here's an image of what my site looks like. Basically when user clicks start video it will add the video item to an array in JSON and log a view. Each time the come back and click that start video button is adds a view. For some members the videos expire after 12 months so I also log a date too. I'll share a snap of the JSON for a video view and share that as well.
     
    Here's a sample of a live member's JSON so you can see how the data's been formatted.
     
    {
      "vodVideos": [
        {
          "views": 1,
          "videoID": "VOD-IND-259",
          "expirationDate": "2024-08-10T15:35:26.708Z"
        },
        {
          "views": 5,
          "videoID": "VOD-IND-289",
          "expirationDate": "2024-08-10T15:40:27.091Z"
        },
        {
          "views": 2,
          "videoID": "VOD-TRN-403",
          "expirationDate": "2024-08-10T15:52:08.299Z"
        },
        {
          "views": 9,
          "videoID": "VOD-CST-368",
          "expirationDate": "2024-08-10T16:09:30.453Z"
        },
        {
          "views": 1,
          "videoID": "VOD-IND-349",
          "expirationDate": "2024-08-10T16:14:05.300Z"
        },
        {
          "views": 3,
          "videoID": "VOD-HAZ-182",
          "expirationDate": "2024-08-13T14:35:24.834Z"
        },
        {
          "views": 1,
          "videoID": "VOD-CST-322",
          "expirationDate": "2024-08-21T15:23:59.300Z"
        },
        {
          "views": 1,
          "videoID": "VOD-IND-321",
          "expirationDate": "2024-08-21T15:24:27.258Z"
        },
        {
          "views": 1,
          "videoID": "VOD-GEN-403",
          "expirationDate": "2024-08-22T15:17:30.073Z"
        },
        {
          "views": 1,
          "videoID": "VOD-CST-403",
          "expirationDate": "2024-08-22T15:30:39.434Z"
        },
        {
          "views": 1,
          "videoID": "VOD-IND-403",
          "expirationDate": "2024-08-22T15:34:07.474Z"
        },
        {
          "views": 1,
          "videoID": "VOD-HAZ-MON",
          "expirationDate": "2024-08-22T15:38:30.529Z"
        },
        {
          "views": 1,
          "videoID": "VOD-TRN-398",
          "expirationDate": "2024-08-22T15:39:05.945Z"
        },
        {
          "views": 4,
          "videoID": "VOD-CST-315",
          "expirationDate": "2024-08-23T17:41:02.529Z"
        },
        {
          "views": 1,
          "videoID": "VOD-IND-292",
          "expirationDate": "2024-08-27T19:12:39.587Z"
        },
        {
          "views": 1,
          "videoID": "VOD-HAZ-179",
          "expirationDate": "2024-08-27T19:18:55.423Z"
        },
        {
          "views": 6,
          "videoID": "VOD-IND-334",
          "expirationDate": "2024-08-27T19:19:21.585Z"
        }
      ],
      "saved-topics": [],
      "completed-topics": [],
      "lastTab_dashboard": 1,
      "lastTab_trainingPlan": 1,
      "notification_LastSeen": "2023-09-11T10:40:16.807Z"
    }
    Hope this is somehow helpful!
    0
  • Comment author
    Alastair Budge

    John Matias you (as always) are an absolute legend. This is exactly what I was trying to achieve with my site. Will play around with this later on today and check if I can make it work. Thank you so much 👍

    0

Please sign in to leave a comment.