Update article.md

Fixed typos / sentence structures
This commit is contained in:
Anton Krekotun 2019-06-07 13:07:07 +03:00 committed by GitHub
parent 3c37e1de7b
commit 3a5647a4fb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -57,7 +57,7 @@ openRequest.onupgradeneeded = function() {
}; };
openRequest.onerror = function() { openRequest.onerror = function() {
console.error("Error", openResult.error); console.error("Error", openRequest.error);
}; };
openRequest.onsuccess = function() { openRequest.onsuccess = function() {
@ -107,13 +107,13 @@ IndexedDB uses the [standard serialization algorithm](https://www.w3.org/TR/html
An example of object that can't be stored: an object with circular references. Such objects are not serializable. `JSON.stringify` also fails for such objects. An example of object that can't be stored: an object with circular references. Such objects are not serializable. `JSON.stringify` also fails for such objects.
**There must be an unique `key` for every value in the store.** **There must be a unique `key` for every value in the store.**
A key must have a type one of: number, date, string, binary, or array. It's a unique object identifier: we can search/remove/update values by the key. A key must have a type one of: number, date, string, binary, or array. It's a unique object identifier: we can search/remove/update values by the key.
![](indexeddb-structure.png) ![](indexeddb-structure.png)
We can provide a key when we add an value to the store, similar to `localStorage`. That's good for storing primitive values. But when we store objects, IndexedDB allows to setup an object property as the key, that's much more convenient. Or we can auto-generate keys. We can provide a key when we add a value to the store, similar to `localStorage`. That's good for storing primitive values. But when we store objects, IndexedDB allows to setup an object property as the key, that's much more convenient. Or we can auto-generate keys.
The syntax to create an object store: The syntax to create an object store:
```js ```js
@ -140,7 +140,7 @@ That's a technical limitation. Outside of the handler we'll be able to add/remov
To do an upgrade, there are two main ways: To do an upgrade, there are two main ways:
1. We can compare versions and run per-version operations. 1. We can compare versions and run per-version operations.
2. Or we can get a list of existing object stores as `db.objectStoreNames`. That object is a [DOMStringList](https://html.spec.whatwg.org/multipage/common-dom-interfaces.html#domstringlist), and it provides `contains(name)` method to check for the existance. And then we can do updates depending on what exists. 2. Or we can get a list of existing object stores as `db.objectStoreNames`. That object is a [DOMStringList](https://html.spec.whatwg.org/multipage/common-dom-interfaces.html#domstringlist), and it provides `contains(name)` method to check for the existence. And then we can do updates depending on what exists.
Here's the demo of the second approach: Here's the demo of the second approach:
@ -190,7 +190,7 @@ db.transaction(store[, type]);
- `readonly` -- can only read, the default. - `readonly` -- can only read, the default.
- `readwrite` -- can only read and write, but not modify object stores. - `readwrite` -- can only read and write, but not modify object stores.
There'is also `versionchange` transaction type: such transactions can do everything, but we can't create them manually. IndexedDB automatically creates a `versionchange` transaction when opening the database, for `updateneeded` handler. That's why it's a single place where we can update the database structure, create/remove object stores. There's also `versionchange` transaction type: such transactions can do everything, but we can't create them manually. IndexedDB automatically creates a `versionchange` transaction when opening the database, for `updateneeded` handler. That's why it's a single place where we can update the database structure, create/remove object stores.
```smart header="What are transaction types for?" ```smart header="What are transaction types for?"
Performance is the reason why transactions need to be labeled either `readonly` and `readwrite`. Performance is the reason why transactions need to be labeled either `readonly` and `readwrite`.
@ -463,7 +463,7 @@ objectStore.createIndex(name, keyPath, [options]);
- **`keyPath`** -- path to the object field that the index should track (we're going to search by that field), - **`keyPath`** -- path to the object field that the index should track (we're going to search by that field),
- **`option`** -- an optional object with properties: - **`option`** -- an optional object with properties:
- **`unique`** -- if true, then there may be only one object in the store with the given value at the `keyPath`. The index will enforce that by generating an error if we try to add a duplicate. - **`unique`** -- if true, then there may be only one object in the store with the given value at the `keyPath`. The index will enforce that by generating an error if we try to add a duplicate.
- **`multiEntry`** -- only used if there value on `keyPath` is an array. In that case, by default, the index will treat the whole array as the key. But if `multiEntry` is true, then the index will keep a list of store objects for each value in that array. So array members become index keys. - **`multiEntry`** -- only used if the value on `keyPath` is an array. In that case, by default, the index will treat the whole array as the key. But if `multiEntry` is true, then the index will keep a list of store objects for each value in that array. So array members become index keys.
In our example, we store books keyed by `id`. In our example, we store books keyed by `id`.
@ -614,7 +614,7 @@ Whether there are more values matching the cursor or not -- `onsuccess` gets cal
In the example above the cursor was made for the object store. In the example above the cursor was made for the object store.
But we also can make a cursor over an index. As we remember, indexes allow to search by an object field. Cursors over indexes to precisely the same as over object stores -- they save memory by returning one value at a timee. But we also can make a cursor over an index. As we remember, indexes allow to search by an object field. Cursors over indexes to precisely the same as over object stores -- they save memory by returning one value at a time.
For cursors over indexes, `cursor.key` is the index key (e.g. price), and we should use `cursor.primaryKey` property the object key: For cursors over indexes, `cursor.key` is the index key (e.g. price), and we should use `cursor.primaryKey` property the object key:
@ -688,7 +688,7 @@ window.addEventListener('unhandledrejection', event => {
### "Inactive transaction" pitfall ### "Inactive transaction" pitfall
A we know already, a transaction auto-commits as soon as the browser is done with the current code and microtasks. So if we put an *macrotask* like `fetch` in the middle of a transaction, then the transaction won't wait for it to finish. It just auto-commits. So the next request in it fails. As we already know, a transaction auto-commits as soon as the browser is done with the current code and microtasks. So if we put a *macrotask* like `fetch` in the middle of a transaction, then the transaction won't wait for it to finish. It just auto-commits. So the next request in it fails.
For a promise wrapper and `async/await` the situation is the same. For a promise wrapper and `async/await` the situation is the same.
@ -715,7 +715,7 @@ The workaround is same as when working with native IndexedDB: either make a new
Internally, the wrapper performs a native IndexedDB request, adding `onerror/onsuccess` to it, and returns a promise that rejects/resolves with the result. Internally, the wrapper performs a native IndexedDB request, adding `onerror/onsuccess` to it, and returns a promise that rejects/resolves with the result.
That works most fine of the time. The examples are at the lib page <https://github.com/jakearchibald/idb>. That works fine most of the time. The examples are at the lib page <https://github.com/jakearchibald/idb>.
In few rare cases, when we need the original `request` object, we can access it as `promise.request` property of the promise: In few rare cases, when we need the original `request` object, we can access it as `promise.request` property of the promise: