Reference tables and javascript

I have a Event collection that references a Venue collection. I’m pulling back a single row of data through the join. This data populates a dynamic page. All the fields on the page work as expected.

But, I have a small amount of javascript used to create a google map and this is where unexpected things happen.

To retrieve data from the Event collection I merely use:
let currentItem = $w(“#dynamicDataset”).getCurrentItem();
console.log( currentItem.title);
console.log( currentItem.date);
/* etc */

But for the fields coming via the join with Venue, the data are deeper nested:

let venue = currentItem.venue._item;
console.log( venue.latitude);
console.log( venue.longitude);
/* etc */

I was expecting all the fields to be at the same level. The join should be transparent at the javascript level, as though I’d pulled it back from a single collection. And to through “_item” is ugly.

What am I doing wrong? I looked for code exampled here but could find nothing.

Thanks

Stephen

I am having difficulties with the same sort of issue - knowing how to reference fields from joined collections. I cant figure out how to do this in wixData.Query( ) or in $w(“#myDataset”).setFilter( ).

Thanks for posting. Looking forward to an answer.

Hi Wix, I got as far as I did by using the debugger built into chrome and examining the contents of currentItem.

I can’t think of a good reason why the structure is as it is, I’m assuming bug.

Looks like there’s been a bug fix to remove the “_item”. This is an improvement but this is still an usual way to implementation of a “join”. I can think of no DBMS that does it this way.

Using my above example I would expect

currentItem.title;
currentItem.date;
currentItem.latitude;
currentItem.longitude;

rather than:
currentItem.title;
currentItem.date;
currentItem.venue.latitude;
currentItem.venue.longitude;

Venue should not be there. The fields from the “join” should be all at the same level.

Also, it would have been really nice if there had been notification given of the bug fix so I could have change my code inline with the release rather than waiting for a user to spot the bug.

Hi,

thank you for your feedback! We do appreciate hearing what you think about the product.

We chose to build it this way, because we see Wix Data as being built around “document” model rather than a more usual “relational” model. We see “joining” as including / embedding another object based on its foreign key into another document. We did this to (1) avoid field collisions (which in relational databases is solved by prefixing with a table name, if some fields were prefixed while others were not, we feel that it would be more confusing) and (2) make it easier to distinguish data from both objects, especially when saving.

Ta. I did suspected it was because of the possibility of duplicated field names. It would cause you to have a messer interface with your collections, which is very simple to use, so I guess this atypical way of returning the data set is the small price to pay.

Perhaps adding a bit of documentation on the subject is all that is required.

Anyway, I’m liking what you’ve done and using wix is a great way to build sites with modest complexity.

Thank you for the good words.

The code part was not considered released, so that is why the documentation wasn’t open. We are opening it soon, so stay tuned.

Thanks. good luck.

Hi Ben,

I was able to resolve this by using the _id of the referenced table in an contains .setFilter(). In a reference table .contains() references the _id of the item.


Short code:

Calling ids:
let options = [{ “value”: ‘’, ‘label’: ‘All Categories’ }];
options.push(…res.items.map(categories => {
return { ‘value’: categories._id, ‘label’: categories.title };
}));

Using ids in filter:
let newFilter = wixData.filter();

if (category)
newFilter = newFilter.contains(‘category’, category);

    $w('#Faqs').setFilter(newFilter); 

Full code:

import wixData from “wix-data”;

$w.onReady( function () {

wixData.query('Categories') 
    .find() 
    .then(res => { 

let options = [{ “value”: ‘’, ‘label’: ‘All Categories’ }];
options.push(…res.items.map(categories => {
return { ‘value’: categories._id, ‘label’: categories.title };
}));
$w(‘#iCategory’).options = options;
console.log(wixData.query(‘Categories’)._id);

    }); 

});

let lastFilterTitle;
let lastFilterCategory;
let debounceTimer;
export function iTitle_keyPress(event, $w) {
if (debounceTimer) {
clearTimeout(debounceTimer);
debounceTimer = undefined;
} {
debounceTimer = setTimeout(() => {
filter($w(‘#iTitle’).value, lastFilterCategory);
}, 200);
}

}

function filter(title, category) {
if (lastFilterTitle !== title || lastFilterCategory !== category) {
let newFilter = wixData.filter();
if (title)
newFilter = newFilter.contains(‘title’, title);
if (category)
newFilter = newFilter.contains(‘category’, category);

    $w('#Faqs').setFilter(newFilter); 


    lastFilterTitle = title; 
    lastFilterCategory = category; 
} 

}

export function iCategory_change(event, $w) {
//let temp = $w(‘#iCategory’).value;
//console.log(temp);
filter(lastFilterTitle, $w(‘#iCategory’).value);

}