Realm database linkingObjects - javascript

While going through the docs encountered these lines on linkingObjects properties please explain them:
"When accessing linkingObjects properties, a Results object is
returned, so further querying and sorting are fully supported.
linkingObject properties belong to the object they were acquired from
and can not be set or manipulated directly. They are updated
automatically when a transaction is committed."

#LinkingObjects is an inverse relationship 0...* that can be automatically evaluated when an object has a 0...1 or 0...* relation to another table.
So when A has a property cats to RealmList<Cat>, then Cat table can have linking objects property to A via linkingObjects("cats"), which is a RealmResults<A>.
What it says however is that you cannot remove items directly from linking objects because it is a computed property, items are only removed from linking objects if the item is removed from the not-inverse relation (the list), or the item is deleted.
When an item is deleted in a transaction, removal of item from linking objects is immediate.

Related

Nodejs, mongoose and problems with queries in a loop

Suppose this scenario.
I have a collection where I store products, this products have a property called "props" and this is an array of objects, that have properties like measure, weight.
The problem comes when I'm trying to insert new products. I'm receiving an array of objects that will be inserted, but each element of the array could have a property called "propsReference", and If it's there, it would be an ID that refers to the object that's currently inserted and have some props
So, if it has the propsReference property with an ID, I want to copy the properties of this object to the object I'm going to insert
The only solution I can think of is doing a foreach to the first array, if it has the propsReference do a query, get the props and insert it into this element of the array as a new property of the object.
But I'm having a lot of problems with doing queries inside a for loop, there's any way in mongoose or something to avoid that?
Thanks in advance

how to add object to firestore first index of object array

i've been googling around about how to add an object into an array in firestore, and found the arrayUnion() able to add an object into firestore array, but it only add the object into last index of array, but how to add it into first index of array?
//add "greater_virginia" into last index of array
washingtonRef.update({
regions: firebase.firestore.FieldValue.arrayUnion("greater_virginia")
});
//how to add "greater_virginia" into first index of array?
its basically same as arrayUnion but instead of add it into last index, i want to add it into first index of array.
If Firestore arrays behave anything like realtime-database arrays, then they don't actually exist. As far as I know, they are store as maps, like:
{
0: "first element",
2: "second and so on",
}
You can probably see how an unshift would be a big transformation. In fact, firestore doesn't let you do this, saying "...in order to avoid some of the issues that can arise in a multi-user environment, you'll be adding them with more of a set-like functionality".
With that in mind, this problem is usually solved at the application level by fetching the array, mutating it as needed, then setting the whole thing.
Bit of further reading https://firebase.googleblog.com/2018/08/better-arrays-in-cloud-firestore.html
PS: be careful with the arrayUnion operator, because it actually performs a add to set
Firestore doesn't offer any way to modify items of array fields by index. arrayUnion will only ever append to the end of the array if the element doesn't already exist.
If you want to modify an array by index, you will have to read the document, modify the array in memory to appear how you want, then write the modified array back to the document.

Polymer JS: Does prepending an item to an Array property re-render the whole UI?

I have a component with following template markup inside it
<template is="dom-repeat" items="{{values}}">
<div><span>{{item.msg}}</span></div>
</template>
This component has a property values which is an Array of objects.
Now I want to prepend item to this array property in response to an event. Does polymer rerender this complete UI throwing away the existing DOM elements, because all the existing elements will pushed down by an index of 1 ? If so, what are optimizations I can implements to avoid DOM rerendering which can be expensive when the Array grows big.
Short answer is no.
It's not about Polymer, it's about dom-repeat.
About dom-repeat behavior, you can see from github.
In simple words for every render
Create index array to apply sort and filter function
Loop through the array of instance (an object from templatize function), assign an item to it if already exist (from previous render)
If not, create a new one, push to array and insert to parent node.
If it has exceeded instances, remove it.
See __applyFullRefresh.
So yes it reuse existing DOM elements.
As I said this is about dom-repeat. You should see iron-list which do similar thing with better performance or create by yourself in the way you want.

Mapping a localStorage variable (an Array of Objects) refuses to work/causes item to disappear

I have an array in my localStorage, product_categories, which holds numerous objects which contain a string and a nested array of objects (the inner objects are the products that belong to each category).
Since Appery's support couldn't help me figure out how to query an array of objects based on an attribute belonging to each object - I just made each object (product) belong to an array and categorize the products based on which array index they were.
Anyway, I am now trying to map an array of objects to my page's collapsible block, which I have done previously - but with a response from the online database.
Now, I am using a SEPARATE service and all I want it to do is grab the array of objects from the localStorage and map it to a collapsible block, or even a grid or list item, so that each index in the array auto-creates a new item.
However, it has not worked for anything I have tried. I tried to map it to every possible item that can have arrays mapped to it, and when I load the page - the item actually disappears, almost as if the array being mapped to it has a length of 0.
But, when I inspect the page in Chrome and look at the localStorage variable that is being used to hold the array of objects (and in-turn mapped to the page), the variable clearly has an array of objects in the same format as other localStorage variables being mapped to the page from storage.
If it helps, I am using a GenericService for pulling the localStorage variables and mapping them to the page. I am not using a custom implementation - all the service does is 'ON SUCCESS - MAPPING' and maps the storage to the page. However, like I said, this isn't working.
Since I have been here for a while but never actually posted or anything, I don't have the rep to post the images that may help in solving my problem; with that in mind, here is the link to the original Appery.io support page which contains corresponding images: https://getsatisfaction.com/apperyio/topics/mapping-localstorage-array-to-collapsible-wont-work-removes-collapsible-item
StackOverflow, I would really appreciate your assistance as I always seem to run into a language barrier when working with Appery.io's support.
*EDIT Your revisions are not useful for my post, as they are changing localStorage to local storage - but in the case of Appery, localStorage is correct syntax.
var products = offlineProductList(); // grab the returned JSON array of products from the function offlineProductList()
var UniqueCats = $.unique(products.map(function (d) {
return d.category // this will return every distinct category
}));
var product_categories = []; // create empty array to hold each category object and its respective products
for(var i=0;i<UniqueCats.length;i++){
// for every unique category...
var category_products = []; // create array to hold products
for(var j=0;j<products.length;j++){
// run through list of products
if(products[j].category == UniqueCats[i]){
// if the product's category is the same as the current indexed unique category, add to array
category_products.push(products[j]);
}
}
var category = {"category":UniqueCats[i],"category_products":category_products}; // create object for the category
product_categories.push(category); // add object to the categorical array
}
localStorage.setItem('product_categories', JSON.stringify(product_categories));
Above is the code used to create the 'array of objects', and below is an image showing the mapping
array of objects mapping to an appery page element
I would give you more but SO won't allow me to with my rep. So if you ask for more I might just 404 myself
So I figured it out myself - Appery actually offers the option for mapping expressions on events like 'Page Load' (for pages/panels etc) and 'Click' (for buttons and similar elements), and I was succesfully able to map localStorage arrays to list, collapsible, and grid elements from there. I guess my GenericService was set up inproperly - but for future users having issues of just mapping something from Storage to the page - just link a mapping expression from an element's event.

ractive js : direct dom insertion sort/order for nested object list associated with #each key section in template

I have seen lots of examples of using array based functions in Ractive for sorting and ordering lists but I was wondering if the same facility could be easily effected for nested object lists:
Assuming something like this:
var ractive = new Ractive({
el: 'main-col',
template: $(templates).html(),
data: {ObjList: {{key1:{x:data,y:dataB,....},{key2:{x:data,y:dataB,....},.. } });
template: {{#each ObjList}} render a card view per each key object nest {{/#each}}
I would like to be able to:
Direct the DOM node/view placement order (not the actual object list per se since it inherently doesn't have an order) as #each nested object key dataset is rendered and
Direct the insertion point of new DOM nodes resulting from ractive auto magic #each templating for new object insertions, at a specific point in the rendered #each list.
For example:
{{#each ObjList}}
<div>key1 data view</div>
<div>key2 data view</div>
<--------Insert new key5 nest object rendering in DOM tree, here
<div>key3 data view</div>
<div>key4 data view</div>
{{/ each}}
I currently have an array of just the key names, that track my desired sort order:
sortArray=[key1,key2,key5,key3,key4...]. I use it as a linked list to traverse nested objects in a specific order for some progressive calculations. But 95% of my code and algorithms align with a keyed nested object list, as opposed to an array of objects.
I have considered three possibilities:
some equivalent array sort like feature that could be easily effected at or post template rendering
creating component instances for each individual nested list object and using the ractive DOM methods or
brute forcing the virtual or real DOM, but I wasn't sure if that would break data binding.
I am 3 days into ractive so I was hoping someone might have a solution that would be the most "ractive" way. Right now my entire view is in a single Ractive instance, and I would like to continue the simplicity of that and the "auto magic" features of new renderings upon inserting a new key object member. The solution also needs to preserve two-way binding.
Why not use a computed property based on your object. Just ractive.get the object data (thus registering a dependency) and return the values sorted however you like. In your template you will iterate through this new computed property. Whenever a new key is inserted, computed property will be updated automatically and then your template/view will be also ractively rerendered
Per my initial intuition, I ended up pursuing choice 2 from my list of possible solutions. I created a component definition for my card view. I then referenced the card component in my parent template,within the parent template #each section/iterator, passing in a key identifier(so I could correlate which component instance was associated with which nested object key in future calls). I also templated things so the same key identifier was assigned to the container div id for each card component instance.
With those relationships in place, I was able to catch the instance event for default rendering(onrender) that auto magic appends new nested data objects to the end of the card view list. I effectively over rode that placement with a subsequent new placement using the ractive.insert method, within the event processing. By passing the parent div id and the desired sibling card div id(anchor) insertion point to ractive.insert, I was able to re-render the new card in the desired order.
While that addresses my original question for the add card use case, it still creates a lingering issue for a second use case: deleting a card. The associated active component instance for a nulled("deleted") nest object key is not removed from the parent container active component list. Nor is it de referenced after explicitly calling teardown for the instance (although it is removed from the view), so its instance specific data functions are still called post "delete." I suspect there is some data binding or teardown cleanup issue going on. I am going to follow up on that use case separately, because of concerns of potential memory leaks and processing overhead for phantom card instances.
See link below for codepen example:
Codepen Link
This codepen demonstrates the default ordering and the sorted version by toggling sort button

Categories

Resources