If i have two related realm objects, e.g:
const PersonSchema = {
name: 'Person', properties: {name: 'string', cars: 'Car[]'},
};
const CarSchema = {
name: 'Car',
properties: {model: 'string', owner: {type: 'linkingObjects', objectType: 'Person', property: 'cars'}},
};
And i need to create a car and reference the owner directly without passing by the Person object and pushing the new created Car...
E.G:
realm.write(() => {
const car = realm.create('Car', {
model: 'Model name',
owner: ownerID
});
});
How can i link the owner object to the car directly instead of: owner.cars.push(car)
Any help PLZ !
I posted this as a comment and re-reading it, it's actually the answer so I hope it helps future readers.
Lists are a one to many relationship of managed objects and the list is stored as a managed property of the parent object.
LinkingObjects on the other hand is more of a "computed property"; their contents are not managed or stored on disk - their values are pulled from existing managed objects in more of a live fashion - similar in concept to a computed property.
e.g. when an object that has a LinkingObjects property is added to a list, its linkingObjects property automagically has a reference to that parent object
So 'adding' an object directly to a LinkingObjects is not possible.
There may be other options though - creating a back link property may be one option - that would allow a one-to-many forward relationship and one to one back relationship. However, the relationship has to be manually managed and the car could only belong to one person. Some pseudo code
Person = {
name: 'Person'
cars: 'Car[]'
}
Car = {
name: 'Car'
belongsTo: Person
}
This setup would allow a person to be added to a Car at any time, keeping in mind that the person won't have a List of their cars until the car is then added to that persons Car[] list manually. That being said, it could be queried
let thisPersonsCars = realm.cars where car.belongsTo == this person
but a List is much more convenient.
Related
I have an array of objects with meta information.
Here is the schema for a object.
this.state.slotData [{
availability: boolean,
id: number,
car: {
RegistrationNumber : string,
Color: string
}, {...}, {...}, ...]
Now, for any incoming car, I record car details
I am further checking if any slots are available, and if so, updating the slotData state.
I filter() the slotData to find all available slots then refer availableSlots[0] to access the id of the nearest empty slot.
Now, I just have to update this.state.slotData without mutating it.
If you want to apply immutable update and add car as a single object in slotData array you should first spread whole slotData array and than add car object like this:
const updatedSlotData = [...slotData, carObj];
this.setState({ slotData: updatedSlotData });
As long as you make a copy first, you can safely mutate the copy.
i'm struggling with declaring and accessing data in nested arrays in Javascript
i can easily do it in C using nested structures, declaring first the lowest-level structure and including an array of it when declaring the upper-level structure and so on. I end up with a structure containing an array of structures, each containing an array of structures, etc...
but i have only 3 days of Javascript experience so far...
Just to help you understand how i need the data to be organized, here's an example:
Let's imagine a library, this library has several floors, each floor has the same type of properties (name, number of books...), each floor has several departments and each has the same type of properties, each department has several shelves and so on...
let's say the 1st floor get's its name from some famous mathematician, and is split into two departments: 1/ arithmetics and 2/ geometry
the ideal for me would be to work with the data this way:
library.floor[0].name = 'Fermat'
library.floor[0].department[0].name = 'arithmetics'
library.floor[0].department[1].name = 'geometry'
library.floor[0].department[1].shelve[4].authors = // authors list
so far i've tried this:
var library =
{
floors: [
{floor_name:'Fermat'},
{has_a_printing_machine:true},
{departments:[
{department_name:'group_theory'},
{shelves:[
{shelf_name:'letters_f_z},
{authors: ["Frobenius","Lagrange"]}]}]}]
};
i can get data from:
log(library.floors[0].floor_name); // ouputs 'fermat'
log(library.floors[2].departments[0].department_name); // outputs 'group_theory'
log(library.floors[2].departments[1].shelves[1].authors[1]); // outputs 'Lagrange'
but it isn't what i need, i can't access a 'departments' property for each floor for instance... and i'd like to add data dynamically in these arrays.
i'm doing it wrong and i can't figure out how to do it right...
thanks for your help!
You're misunderstanding JavaScript object literals. They are completely different that structs in C. Structs are type declarations, JavaScript object literals are actual objects.
You should stop putting one key/value pair per object, and start making uniform objects that contain the same attributes.
When you write [ { department_name: ... }, { shelves: ... } ] you are defining an array that contains two unrelated objects, one containing a department_name property, and the other containing a shelves property. These objects know nothing about each other, or that they are contained in the same array.
Instead of this...
[
{
department_name: 'group_theory'
},
{
shelves: [
{
shelf_name: 'letters_f_z'
},
{
authors: ["Frobenius","Lagrange"]
}
]
}
You should be writing:
{
departments: [
{ # This entire object is a department. It has a name and shelves
name: 'group_theory',
shelves: [
{ # This entire object is a shelf. It has a name and authors.
name: 'letters_f_z',
authors: ["Frobenius","Lagrange"],
}
]
}
]
}
To put it a different way, when you write this...
floors: [
{floor_name:'Fermat'},
{has_a_printing_machine:true},
{departments:[...]}
]
You are not making an array of floors, you're making an array of three totally unrelated objects, one that contains a floor_name property, one that contains a has_a_printing_machine property, and one that contains a departments property. If you want all three objects to have all three properties, you need to declare them that way:
floors: [
{ name: 'floor_one', has_a_printing_machine: true, departments: [] },
{ name: 'floor_two', has_a_printing_machine: false, departments: [ ... ] },
{ name: 'floor_three', has_a_printing_machine: true, departments: [] },
]
You almost had it. Each floor is an entity on its own, with its properties. One of its properties is the list of departments, and each department is an entity itself too (again, with its own properties). And same with the shelves.
Each instance of an entity/struct/register is a dictionary, with its properties mapped as key:value pairs. So, for instance, a shelf could be:
var my_shelf = {
shelf_name:'letters_f_z',
authors: ["Frobenius","Lagrange"]
};
A department (with its shelves) may be:
{
department_name:'group_theory',
shelves:[
{
shelf_name:'letters_f_z',
authors: ["Frobenius","Lagrange"]
},
{...}
]
}
I think at this point you can extrapolate this construction to the floors level, having an array of department registries as the value of the departments property.
Unfortunately, unlike TypeScript, which is a statically-typed superset of JavaScript, you can't enforce each register to actually have a certain set of properties. So you'll have to be extra-cautious when creating the instances so every property is initialized since its very beginning.
I have a class (LiveScript) that is instantiated once, but its render method is called many times. Each object created in the render method must have a unique key that stays the same across all invocations of render:
class Test
->
console.log 'constructor, called only once'
render: ->
test = {key: 4124312}
test1 = {key: 234897}
test2 = {key: 87234}
This works, but instead of hardcoding the key I'd rather generate it. Using a random number will not work since that will generate a new key on each invocation of render. Having some list of keys outside this class and popping items of them won't work either because the order of the created objects in render could change. Any idea if and how I could generate the keys?
Generating them is one thing - it sounds like you need a way to persist the unique objects with a key that doesn't change during your execution context. This is called persistence.
In JS, you can use an object literal to store your objects, where the key of each entry in your storage object is the unique key of your stored objects:
{
1234: { name: "test", key: 1234 },
2345: { name: "test1", key: 2345 },
3456: { name: "test2", key: 3456 }
}
I am new to constructing a JavaScript Array prototype. Please only paste previous links that are directly appropriate as I have been sourcing on SO and on w3school.
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/prototype
I would like to create a method for an array that checks if the 'id' field within the object does not already exist in the array. If not, then 'push' object into the array, else do nothing.
Each object has a unique 'id' field.
eg
var array = [{ id: 001, title: 'some title'},
{ id: 002, title: 'other title'}]
var object = {id: 001, title: 'some title'}
// if object.id does not exist in array...
array.push(object)
//else do nothing
I would like the function to take the 'id' field as an argument so this function has wider use.
Are there any drawbacks to extending the array.Prototype? Otherwise I can do a for loop instead to do the check without the prototype constructor.
Since your ids are integers you could just set that index in the array directly.
var array = [];
var object = {id: 001, title: 'some title'};
array[object.id] = object;
That will overwrite the element in that location such that you won't get duplicates with the same id. Your js engine will automatically switch to using a sparse array rather than a contiguous array if your ids are far apart.
Instead of trying to change the behavior of Array consider using an object instead of array with the id as the key.
var objects = {};
var object = {id: 001, title: 'some title'}
objects[object.id] = object;
That way you can also retrieve your objects from the parent object by their id. e.g.
var result = objects[001];
I found brads's answer using the function containsObject
How do I check if an array includes an object in JavaScript?
This does a check so there is no extra writes to the database such as overwrites. Thank you everyone for inputting towards the question. It has helped.
I've created an ashx page which is going to serve me an XML document full of basic user information. I'm not sure which is the best way to go about creating and populating my custom javascript object. I've seen them created in two ways:
function User() {
this.Id;
this.FirstName;
this.LastName;
this.Title;
}
and
var User2 = {
Id: null,
FirstName: null,
LastName: null,
Title: null
}
I could populate each of these by doing something like:
//first object
User.Id = 1
//second object
User2.FirstName = 'John'
Is one method of creating the object better than the other?
Edit: A year and a half later I saw that this question got the popular badge, so I just wanted to mention that today I am using Crockford's module pattern.
You cannot access the first object's properties without instantiation, i.e. using the new keyword:
var myUser = new User() ;
document.write(myUser.id) ;
The second object is an object literal which is accessible without instantiation as it is already instantiated when parsed.
The difference comes into play if you want use prototypical inheritance to create a new object on basis of the old one. Writing an object literal is probably easier to understand and the more appropriate pattern if you have a rather compact code base. However, prototyping comes in handy if you want to create a new object by augmenting an existing object with another object without having to rewrite the object getting augmented:
ipUser.prototype = User ;
ipUser.ip = "128.0.0.1" ;
In your case this difference might not seem striking, but you have to imagine how much redundant code you would get if you would create another object literal for every meager addition to the original object.
Look into the Mozilla Developer Center's page on JavaScript Objects if you have additional questions, it's outlined pretty well: https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference:Global_Objects:Object .
Hth
You don't have to create an object with empty values first. JavaScript doesn't need place holders and can add properties and methods dynamically at any time. That is, this would suffice as well:
var User2 = {};
User2.Id = 1;
User2.FirstName = 'John';
//...Etc.
If you're just concerned about storing data I'd use this form (the object literal, ie. your second method).
Update: You could also make things a bit easier and create a function that creates user objects for you:
function createUser(id, firstname, lastname, title) {
return {
Id: id,
FirstName: firstname,
LastName: lastname,
Title: title
};
}
var User2 = createUser(1, 'John', 'Smith', 'Manager');
The first is a typical object, known from OOP. You can add functions to act on the attributes like this (assuming there is a function getFullName):
var u = new User();
u.getFullName();
The second one is just an associative array, in which strings are mapped to values.
In JavaScript the boundary between the two is not as strict as in ohter programming languages.