Blank entries in collection with same ownerid

I am manually creating entries in collections via code. Since I can’t use standard elements as the input is used for both first time input, as well as updating values. However I am getting consistently extra blank entries and I am not sure why.

I have removed a large part of my code so it is easier to follow as the vast majority of it has nothing to do with inserting data. The part in question is the “memberplannerinfo” collection. I get duplicate entries for the same ownerid and for the life of me can’t figure it out. It has never happened to me on sandbox. And I don’t think it always happens on live site as I would expect far more duplicates if it did.

Main idea is that users create initial content. If they do not have an entry, create an initial object with their ownerid as a key field. If there is data set this object = the already existing data. This object is called toInsert.

Then I update toInsert with various data depending on what they are doing. OR I update data with information from this object. Every place I either update, or insert I have added some things for “how” the record should be created/updated. However the blank rows are just completely blank except for system generated fields, ownerid, _id, created date etc…

Can anyone see why I am getting extra rows of junk data?

//import Chart from 'chart.js'
import wixData from 'wix-data'
import wixUsers from 'wix-users'
import wixWindow from 'wix-window'
import {memory} from 'wix-storage'
import wixLocation from 'wix-location';

var toInsert = {}
var myInfo
var attempts = 0
var success = false
var abortRun = 0

$w.onReady(async function () {
	updateHTML()	
	myInfo = await wixData.query("memberPlannerInfo")
		.eq("_owner",wixUsers.currentUser.id)
		.find()	
	if (myInfo.items.length > 0){
		toInsert = myInfo.items[0]		
		$w('#allergies').value = myInfo.items[0].myAllergies
		$w('#dietType').value = myInfo.items[0].dietType
		$w('#height').value = myInfo.items[0].height
		$w('#weight').value = myInfo.items[0].weight
		$w('#age').value = myInfo.items[0].age
	}
	else {
		toInsert._owner = wixUsers.currentUser.id
	}

});

async function updateHTML(){
	//DO SOME STUFF	
}

async function calculateMealsNew (mealPlan){
    //No Data stuff here
}
	

async function startPlan(){	
	await calculateMealsNew(mealPlan)
	if (abortRun == 0){
		success = true
	}
	else{
		abortRun = 0
	}			
	
	/*THE INSERT PART */

	if (success == true){
		await wixData.bulkInsert("myMealsTest", mealPlan);		
		$w('#myPlan').refresh()
		$w('#snacks').refresh()
		$w('#columnStrip4').collapse()
		wixWindow.scrollTo(0, 0)
		updateHTML()
	}	
	
}		
	
		
	 
  	
export async function myPlan_ready() {
	var dt = new Date()	
	await $w('#myPlan').setFilter(wixData.filter()
		.gt("time",0)
		.lt('time',4)
		.eq("_owner",wixUsers.currentUser.id)
		.eq('day',dt.getDay())		
		)
if ($w('#myPlan').getTotalCount() === 0) {
      $w('#columnStrip4').expand()
    }
	
}

export async function GetMealPlan_click(event) {
	//console.log("starting plan")
	wixWindow.openLightbox("Welcome")
	attempts = 0
	while (attempts <3 && success == false){
		await startPlan()
	}
	
	toInsert.myAllergies = $w('#allergies').value
	toInsert.dietType = $w('#dietType').value
	toInsert.calories = parseInt($w('#totalCalories').text,10)
	toInsert.height = parseInt($w('#height').value,10)
	toInsert.weight = parseInt($w('#weight').value,10)
	toInsert.age = parseInt($w('#age').value,10)
	if (myInfo.items.length > 0){
		toInsert.email = await wixUsers.currentUser.getEmail()
		await wixData.update("memberPlannerInfo",toInsert)
	}
	else{
		console.log("added a new one by toInsert")
		toInsert.howCreated = "toInsert"
		toInsert.email = await wixUsers.currentUser.getEmail()
		await wixData.insert("memberPlannerInfo",toInsert)
	}
}

/**
 *	Adds an event handler that runs when the element is clicked.
 *	 @param {$w.MouseEvent} event
 */
export async function image1_click(event,$w) {	
	//let $item = $w.at(event.context)
	const myItem = await $w("#myPlan").getCurrentItem()
	//console.log(myItem)
	memory.setItem("MealDash", myItem._id)
	wixLocation.to(myItem.meal['link-meals-title'])
	

}

async function deleteMeals(){
	let removeList = []
	let myMeals = await wixData.query("myMealsTest")
		.eq("_owner",wixUsers.currentUser.id)
		.find()
	for (let i = 0; i<myMeals.items.length;i++){
		removeList.push(myMeals.items[i]._id)
	}
	wixData.bulkRemove("myMealsTest",removeList)
}

export async function customPlan_click(event) {
    //Someone can manually trigger to restart.  Populates initial input fields with data from their previous entry, but replaces calories with 
    //their custom entry
    
	myInfo = await wixData.query("memberPlannerInfo")
		.eq("_owner",await wixUsers.currentUser.id)		
		.find()		
	toInsert = myInfo.items[0]
	//console.log("seting selction tags to ",myInfo.items[0].myAllergies)
	$w('#allergies').value = myInfo.items[0].myAllergies
	$w('#dietType').value = myInfo.items[0].dietType
	$w('#height').value = myInfo.items[0].height
	$w('#weight').value = myInfo.items[0].weight
	$w('#age').value = myInfo.items[0].age	
	toInsert.calories = parseInt($w('#customCalories').value,10)
	$w('#totalCalories').text = $w('#customCalories').value
	console.log("using this data",toInsert)

	toInsert.howCreated = "CustomPlan"
	wixData.update("memberPlannerInfo",toInsert)
	$w('#box1').collapse()
	await deleteMeals()
	attempts = 0
	success = false
	while (attempts <3 && success == false){
		await startPlan()
	}
	
}

export async function NewMealPlan_click(event) {	
	$w('#box1').expand()
}

export async function StartOver_click(event) {
    //Similar to above but just starts completely over and lets people pick initial values again
	await deleteMeals()
	$w('#columnStrip4').expand()
	$w('#box1').collapse()
	wixWindow.scrollTo(0, 0)
}

archaeous you are not a beginner, please use —> CODE-TAGS / CODE-BLOCKS

sorry about that, hit the code snippet first then pasted and it got removed. Should have noticed. I updated it as proper code.

@archaeous
Tried to reconfigure your CODE, to make it perhaps a little bit better readable.

//import Chart from 'chart.js'
import wixData from 'wix-data'
import wixUsers from 'wix-users'
import wixWindow from 'wix-window'
import {memory} from 'wix-storage'
import wixLocation from 'wix-location';

var DATASET1 = "myPlan"
var DATASET2 = "snacks"

var myInfo, toInsert = {}, attempts = 0, success = false, abortRun = 0;

$w.onReady(async()=>{
    updateHTML(); 
    myInfo = await wixData.query("memberPlannerInfo")
    .eq("_owner",wixUsers.currentUser.id).find() 
    if (myInfo.items.length > 0){
        toInsert = myInfo.items[0] 
        $w('#allergies').value = myInfo.items[0].myAllergies
        $w('#dietType').value = myInfo.items[0].dietType
        $w('#height').value = myInfo.items[0].height
        $w('#weight').value = myInfo.items[0].weight
        $w('#age').value = myInfo.items[0].age
    } else {toInsert._owner = wixUsers.currentUser.id}

    $w('#'+DATASET1).onReady(async()=>{
       var dt = new Date();
       await $w('#'+DATASET1).setFilter(wixData.filter()
          .gt("time", 0)
          .lt('time', 4)
          .eq("_owner", wixUsers.currentUser.id)
          .eq('day', dt.getDay()) 
       )
       if ($w('#'+DATASET1).getTotalCount()===0) {$w('#columnStrip4').expand();}
    });


 //*********** onClick-Control-Section ****************************************
  //--------- New Meal-Plan ----------
    $w('#NewMealPlan').onClick(()=>{$w('#box1').expand();});
 
  //--------- Get Meal-Plan ----------
    $w('#GetMealPlan').onClick(async()=>{console.log("starting plan");
        wixWindow.openLightbox("Welcome");
        attempts = 0
        while (attempts <3 && success == false){await startPlan();}
        //--------------------
        toInsert.myAllergies = $w('#allergies').value
        toInsert.dietType = $w('#dietType').value
        toInsert.calories = parseInt($w('#totalCalories').text,10)
        toInsert.height = parseInt($w('#height').value,10)
        toInsert.weight = parseInt($w('#weight').value,10)
        toInsert.age = parseInt($w('#age').value,10)
        //--------------------
        if (myInfo.items.length > 0){
           toInsert.email = await wixUsers.currentUser.getEmail()
           await wixData.update("memberPlannerInfo",toInsert)
        }
        else{console.log("added a new one by toInsert")
            toInsert.howCreated = "toInsert"
            toInsert.email = await wixUsers.currentUser.getEmail()
            await wixData.insert("memberPlannerInfo",toInsert)
        }
    });

    //--------- ????? ----------
    $w('#image1').onClick(async(event,$w)=>{console.log("starting plan");
       //let $item = $w.at(event.context)
       const myItem = await $w('#'+DATASET1).getCurrentItem()
       //console.log(myItem)
        memory.setItem("MealDash", myItem._id)
        wixLocation.to(myItem.meal['link-meals-title'])
    });

    //--------- Custom-Plan ----------
    $w('#customPlan').onClick(async(event)=>{//manually trigger to restart.  
       //Populates initial input fields with data from their previous entry, 
        but replaces calories with their custom entry.

        myInfo = await wixData.query("memberPlannerInfo")
        .eq("_owner",await wixUsers.currentUser.id) 
        .find()
        toInsert = myInfo.items[0]; 
        //console.log("seting selction tags to ",myInfo.items[0].myAllergies)
        $w('#allergies').value = myInfo.items[0].myAllergies
        $w('#dietType').value = myInfo.items[0].dietType
        $w('#height').value = myInfo.items[0].height
        $w('#weight').value = myInfo.items[0].weight
        $w('#age').value = myInfo.items[0].age  
        toInsert.calories = parseInt($w('#customCalories').value,10)
        $w('#totalCalories').text = $w('#customCalories').value
        console.log("using this data",toInsert)

        toInsert.howCreated = "CustomPlan"
        wixData.update("memberPlannerInfo",toInsert)
        $w('#box1').collapse();
        await deleteMeals();
        attempts = 0, success = false
        while (attempts <3 && success == false){await startPlan()}
     });

     //--------- Custom-Plan-Over ----------
     $w('#StartOver').onClick(async(event)=>{
 //Similar to above but starts completely over & lets people pick initial values again
        await deleteMeals()
        $w('#columnStrip4').expand()
        $w('#box1').collapse()
        wixWindow.scrollTo(0, 0)
    });
});


//---------- FUNCTIONS --------------------------------------------------------
async function updateHTML(){/*DO SOME STUFF here */}
async function calculateMealsNew (mealPlan){/*No Data stuff here*/}

async function startPlan(){ 
 await calculateMealsNew(mealPlan);
 if (abortRun == 0){success=true;} else{abortRun = 0;} 

 /*THE INSERT PART */
 if (success == true){
 await wixData.bulkInsert("myMealsTest", mealPlan); 
        $w('#'+DATASET1, '#'+DATASET2).refresh();
        $w('#columnStrip4').collapse();
        wixWindow.scrollTo(0, 0); updateHTML();
 } 
} 

async function deleteMeals(){
 let removeList = []
 let myMeals = await wixData.query("myMealsTest")
 .eq("_owner",wixUsers.currentUser.id)
 .find()
 for (let i = 0; i<myMeals.items.length;i++){
        removeList.push(myMeals.items[i]._id)
 }
    wixData.bulkRemove("myMealsTest",removeList)
}

Perhaps with a little bit better readable structure you will be able to find your issue. USE MORE CONSOLE_LOGS!!! → Use them almost on every of your code-lines, to inspect every single line of your code.

@russian-dima Yes I definitely need to get more organized. It is one of my bigger issues when it comes to coding. I will take a look. I did have more console logs I had removed a lot of stuff to make the code more concise. It was almost 2000 lines without my deletions :smiley:.
I will take a look and see if I can find the issue in what you posted.

@archaeous Yes, you should of course delete all unneccessary console-logs after you have found your BUG. I use console-logs, just either for DEBUGGING, or to understand my code, a little bit better, if the code gets more complex.

If everything is working, delete all anymore needed logs, and just do add some COMMENTS for later coding.

@russian-dima Unfortunately I have not been able to find the issue as of yet. But I really appreciate the rewrite, it shows me how to do a lot of things significantly better. When my code was only a few dozen lines long with a function or 2 it didn’t matter so much, but this page is getting quite complex. Outside of the question of what I am doing wrong I notice that you use syntax such as

$w('#customPlan').onClick(async(event)=>{})

instead of using the functions like these

export async function customPlan_click(event){}

is there a difference in how these behave or is it more stylistic? One place I see a possible difference is when an onready is placed under the pages onready. If there are times where the page isn’t ready, and the dataset is I could see using your syntax being better as both would need to be ready if I am reading it correctly.

I will continue to look to see if I can find a reason. I am doing cleanup work every so often to delete these records. It doesn’t seem to hurt anything much (I need to put in checks to load the value with data if multiples are returned) But that is only if I can’t resolve the issue.

@archaeous
There are several advantages to go my way of coding…

  1. Yes → You are right with the → onReady it is more simple & efficient.
  2. You never will loose connection to the wix-property-panel anymore.
  3. Code has better STYLING → better readable.
  4. Even more compact.
  5. You can devide in READY-SECTION and FUNCTIONs, like i do it always.
  6. You won’t have to jump-up & down all the way in your code, searching for some code-parts (at least you will scroll-up & down less).
  7. Time-saving coding…
  8. I do also not use to much spaces in my code…
bad:
$w.onReady( ( ) = > {

better:
$w.onReady(()=> {

The more compact and structured your code -->the better overview you will have
The better overview you will have → The better readable will be your CODE.
The better readable will be your CODE → The less BUGS will will find in your code

Logical way of thinking including logical conclusions :wink:.

You will find more hints on how to code better, directly in your own CODE…

bad:
$w('#'+DATASET1').refresh();
$w('#'+DATASET2').refresh();
better:
$w('#'+DATASET1,'#'+DATASET2).refresh();

And so on…

Take care of your code-structure and syntax, and you will have less ERRORS, 4-sure!

And the biggest reason to code in a good quality-manner —>

When my code was only a few dozen lines long with a function or 2 it didn’t matter so much, but this page is getting quite complex
And like always —> do not forget to like it, if you really liked it :wink: