Dexiedb Put method not working when adding primary key as argument - dexie

i am using dexiedb for my angular project. I have a database with a comments table. I would like to add the user inputs to the database and i am using table.put(item, [key]). I want to only add in the first row, so primary key = 0, thats why i specify the key. But it is not working.
Below is my code snippet. I am getting error when having the primary key as argument.
Failed to execute 'put' on 'IDBObjectStore': The o… in-line keys and the key parameter was provided.",
#Injectable()
export class DexieService{
onNewComment = new EventEmitter<Comments>();
contactDB: Dexie;
constructor(){
this.contactDB = new Dexie('contact');
this.contactDB.version(1).stores({
comments:'++id,comment'
})
}
addComment(comment: Comments): Promise<any>{
return(
this.contactDB.table('comments').put(comment,0)
.then((result) =>{
this.onNewComment.next(comment);
return (result);
})
)
}
Expected result should be that when any new comments are added, it will always go to first row with primary key = 0 as the primary key already exists

Your primary key (++id) is inbound, which means you can only specify the key within the object itself and do not need to use the optional key parameter. The API will fail if using the optional key argument unless the primary key is outbound. This API mirrors the raw IndexedDB's IDBObjectStore.put() method that works the same for inbound keys.
Instead, use:
this.contactDB.table('comments').put({...comment, id: 0})

Related

Simple write to Dexie without knowing the schema

Is it possible to write an entire object to Dexie without knowing the schema?
I just want to do this:
var db = new Dexie(gameDataLocalStorageName);
db.version(1).stores({
myData: "gameData"
});
db.myData.put(gameData);
console.log(db.myData.get('gameData'));
But I'm getting the following error:
Unhandled rejection: DataError: Failed to execute 'put' on 'IDBObjectStore': Evaluating the object store's key path did not yield a value.
DataError: Failed to execute 'put' on 'IDBObjectStore': Evaluating the object store's key path did not yield a value.
The error is because you've specified the schema to use inbound key "gameData", i.e. require each object to have the property "gameData" as its primary key.
If you don't need to have the primary key within the objects, you can declare the schema as {myData: ""} instead of {myData: "gameData"}. By doing so, you will need to provide the primary key separate from the object in calls to db.myData.put().
See docs for inbound vs non-inbound keys and detailed schema syntax
var db = new Dexie(gameDataLocalStorageName);
db.version(1).stores({
myData: ""
});
Promise.resolve().then(async () => {
await db.myData.put(gameData, 'gameData'); // 'gameData' is key.
console.log(await db.myData.get('gameData'));
}).catch(console.error);
Since we're changing the primary key here, you will need to delete the database in devtools before this would work.

Modifying an array property of a resource (participant) during a transaction

I want to modify a property of a participant which is an array of relationships during a transaction.
Let's assume I have a user that holds an array of keys like so:
participant User identified by userId {
o String userId
--> Key[] keys
}
asset Key identified by keyId {
o String keyId
}
transaction modifyUserKeys {
--> User user
}
Then in the transaction processor function I modify the array (as in adding and removing elements in it) and update the participant:
function modifyUserKeys(tx) {
let user = tx.user;
// create a new key via factory
var newKey = ...
user.keys.push(newKey);
return getParticipantRegistry('com.sample.User')
.then(function (participantRegistry) {
return participantRegistry.update(user);
});
}
In the documentation I saw a method called addArrayValue() which adds an element to an array. Now I'm unsure whether I'm meant to use this over conventional array manipulation like in my example.
What purpose does this addArrayValue() method have and am I able to e.g. remove elements from keys via keys.pop() or is it restricted to just the addition of new elements like the documentation suggests?
you can use conventional (push/pop) if you like (and as you've done on the array), but newKey would need to use newRelationship()
a useful example similar to what you're trying to achieve is here -> https://github.com/hyperledger/composer-sample-networks/blob/master/packages/fund-clearing-network/lib/clearing.js#L151 in Composer sample networks - addArrayValue() is also validating that it does not violate the model

WIX.com Primary key to be used as reference

I'm new to the WIX web development platform.
I need to use the Primary Key of Table 1 to be used as a reference of Table 2, but I cannot use the ID of table 1 for this purpose.
I wonder if the best way is to "copy" this ID in the Title field (Primary Key) of this table 1. How I do that? Is this the best method?
Thank you,
Arturo
Arturo:
Have you tried doing this without using wix code?
Check out this post to see if it is possible.
Now in code the only way to add a reference field from another data collection is to use the ID. But note that ID is the field name used in the data collection for dashboard and Editor view. When accessing the ID value in code you need to use the field key which is _id.
So in your Table2 you need a column (field) that is of type reference and give it a field name like "Table1 Reference". The editor will generate a field key for you that will look like table1Reference.
Now if you have a record from Table1 that you want to link to Table2 you do something like this:
wixData.query('Table1')
.eq('title', 'uniqueTitle')
.find()
.then((results) => {
if (results.totalCount !== 1) {
throw Error('We didn't get a record from Table1');
}
// Success add this in a new record in Table2
let table1Item = results.items[0];
let table2Data = {
table1Reference:table1Item._id,
anotherTable2Field:"Some info for table2"
};
return wixData.save('Table2', table2Data)
.then((savedRecord) => {
// Successful save!
// Do something here....
});
})
.catch((error) => {
console.log(error);
});
Good luck!
Steve

Why is my Enitty.Contains(attributeField) returning false when I am able to set the value?

I have a block of code that is not working as I thought it would.
I have set an Entity up as follows and have a previous guid.
parentEnt = new Entity("vehicle_ent");
parentEnt.id = guid;
Now when I do a check with a statement:
if (parentEnt.Contains("attribute_field")) {
parentEnt["attribute_field"] = "test";
}
The above will never be called because the if statement fails.
However, if I remove the if statement. I am able to actually assign and run the code:
parentEnt["attribute_field"] = "test";
Is there something I am missing with the Contains Method? I thought it was used to check if the Entity contains the attribute?
On the Entity class, you can always assign an attribute like the example you provided whether or not it exists. If it exists, it will overwrite it (which is what you discovered).
So
parentEnt["attribute_field"] = "test";
Will always work, whether or not the attribute already has a value assigned.
When you run the constructor for a CRM entity object, and assign it a guid
Like
Entity parentEnt = new Entity("vehicle_ent");
parentEnt.id = guid;
you are creating a new object of the entity type with the 'vehicle_ent' logical name and a id of 'guid' At this point all the attribute/properties that belong to an entity with that name, are not created along with the entity object, and you only have an Entity class object with a LogicalName and id set.
If you want to check if an entity record with that id contains a certain attribute, you need to fetch is from the database, using your the organization service, like
ColumnSet attributes = new ColumnSet(true);
parentEnt = _service.Retrieve("vehicle_ent", guid, attributes);
After the retrieve is called you can check if the entity record contains the attribute you need to check.
I just add a couple of things:
The syntax entity[attributename] and entity.Attributes[attributename] are equivalent, the reason can be found inside the Entity metadata:
public object this[string attributeName] { get; set; }
the method maps at entity level the Attributes property (the type of this property is AttributeCollection an inherit from DataCollection<string,object> and the base type is an IEnumerable<KeyValuePair<TKey, TValue>>)
DataCollection contains this method:
// Summary:
// Gets or sets the value associated with the specified key.
//
// Parameters:
// key:
// Type: TKey. The key of the value to get or set.
//
// Returns:
// Type: TValue The value associated with the specified key.
public virtual TValue this[TKey key] { get; set; }
this method adds the key (our attributename) inside the collection if the key is not present before. For this you can assign a value to an attribute without using the Contains method first. Of course when you read the value you need to check if the key is present, this is the purpose of the Contains method, but to read the values the GetAttributeValue can be used as well (but it's necessary to pay attention to the default values returned when the attribute is not inside the collection)

Codeigniter MY_Model composite primary key

I'm working with a base class MY_Model for accessing the database, which contains all the CRUD methods. The model which I'm using is Jens Segers' MY_Model:
https://github.com/jenssegers/CodeIgniter-My-Model
Now, I have a table in my database which contains a composite primary key (article_id and tag_id). Normally, when the primary key contains only an ID for instance, I could just use:
protected $primary_key = "id";
Is there a possibility for a composite primary key, or should I add a column ID to be the only primary key?
Thanks in advance.
Don't sacrifice your database structure because the custom library you are using doesn't support exactly what you need.
There's a work around however:
That library uses CI's database library and uses the $primary_key in the db->where() function.
That function accepts the following argument formats:
$this->db->where('name', $name);
$this->db->where($array);
$this->db->where($where);//$where is a custom MySQL query string
Therefore, you CANNOT set a composite primary key by setting:
$primary_key = array("article_id", "tag_id");
as the library constantly uses the first method of the where() method above.
Instead, just supply methods like get() or insert() (or other) each time with array("article_id" => $article_id, "tag_id => tag_id).
The database will throw an error if you try and insert anything matching your primary key, so you can deal with that then.

Resources