質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Chrome extension

Chrome拡張機能

Q&A

解決済

1回答

1267閲覧

chrome.storageでうまいことデータを保存したい

ganariya

総合スコア50

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Chrome extension

Chrome拡張機能

0グッド

1クリップ

投稿2018/07/29 13:07

前提・実現したいこと

「競技プログラミングブックマーク」
現在、競技プログラミングのサイトにjQueryなどでチェックボックスなどを埋め込み
そのチェックボックスを押すことでURLや問題のタイトルなどをstorageに拡張して、
マイページにその情報を羅列することで復習などに役立てる、クローム拡張を作成しようとしています。

そのために、AtCoder、Codefoces、CSAcademyなどのサイトにjQueryでボタンを埋め込み、ボタンを押すとchrome.storage.localやsyncに、情報を含んだオブジェクトを格納する必要があります。
プロトタイプは完成しており、どう情報を格納するかを考えています。

質問1

できる限りsyncでストレージに保存して、同期的にデータを保存したいと考えています。
そのため、ストレージに格納するオブジェクトを入れ子構造にしてうまいことsyncの制約を満たしながらオブジェクトを作成したいです。

もう一度解きたい競技プログラミングのページを保存するためには

の情報をストレージに格納する必要があります。

現在考えているオブジェクト構造としては

ルート ーatcoder(サイト名) ーー0(開催回) ーーー{site: サイト名, times: 開催回, level: 難易度, title: タイトル, url:URL} ーー34 ーーー{site: サイト名, times: 開催回, level: 難易度, title: タイトル, url:URL} ーcodeforces ーー32 ーーー{site: サイト名, times: 開催回, level: 難易度, title: タイトル, url:URL}

上記のようにしたいと考えています。

どのように実現すればいいでしょうか。
arrayでpushをして実装しようとしたのですが、c++と違い、重複をなくすsetがないため複数存在してしまったり、配列が宣言されておらずエラーが出たりしてしまいます。

質問2

chrome.storageでオブジェクトを保存する時、同じキーのものが上書きされてしまいます。
例えば、以下のような状況です。

javascript

1 2 var obj1 = { 3 atcoder: [ 4 { 5 url: 'url1', 6 num: 1 7 }, 8 { 9 url: 'url2', 10 num: 1 11 }, 12 { 13 url: 'url3', 14 num: 1 15 } 16 ] 17 }; 18 var obj2 = { 19 codeforces: [ 20 { 21 url: 'url10', 22 num: 11 23 }, 24 { 25 url: 'url12', 26 num: 12 27 }, 28 { 29 url: 'url3', 30 num: 13 31 } 32 ] 33 }; 34 35 var obj3 = { 36 atcoder: [ 37 { 38 url: 'url10', 39 num: 10 40 }, 41 { 42 url: 'urlfdasfads2', 43 num: 1 44 }, 45 { 46 url: 'urlafsfafads3', 47 num: 1 48 } 49 ] 50 }; 51 52 chrome.storage.local.set(obj1); 53 chrome.storage.local.set(obj2); 54 chrome.storage.local.set(obj3); //問題点

上記の場合、最終行のobj3を追加する行で、obj1の情報が消えてしまいます。

そこで、以下のことを実行してみました。

javascript

1 2 chrome.storage.local.set(obj1); 3 chrome.storage.local.set(obj2); 4 5 chrome.storage.local.get('atcoder', function (items) { 6 items.atcoder.push(obj3.atcoder[0]); 7 chrome.storage.local.set(obj3); 8 })

予めデータを取得しておき、追加したものをまたsetし直すという方法です。
しかし、get内でsetをしてみると実行されておらず、結果が反映しておりませんでした。
また、function(items)ないからitemsを取り出す方法もなく、データを上書きしてしまいます。

補足情報(FW/ツールのバージョンなど)

  • OS: Mac
  • IDE: Webstorm
  • package.json

json

1{ 2 "name": "atcoder_save", 3 "version": "1.0.0", 4 "description": "", 5 "main": "index.js", 6 "scripts": { 7 "build": "webpack --mode=development", 8 "start": "webpack --watch --mode=development" 9 }, 10 "author": "", 11 "license": "ISC", 12 "dependencies": { 13 "babel-core": "^6.26.3", 14 "babel-loader": "^7.1.5", 15 "babel-preset-env": "^1.7.0", 16 "bulma": "^0.7.1", 17 "copy-webpack-plugin": "^4.5.2", 18 "css-loader": "^1.0.0", 19 "extract-text-webpack-plugin": "^4.0.0-beta.0", 20 "moment": "^2.22.2", 21 "node-sass": "^4.9.2", 22 "postcss-loader": "^2.1.6", 23 "sass-loader": "^7.0.3", 24 "scss-loader": "0.0.1", 25 "style-loader": "^0.21.0", 26 "vue": "^2.5.16", 27 "vue-loader": "^15.2.6", 28 "vue-router": "^3.0.1", 29 "vue-template-compiler": "^2.5.16", 30 "webpack": "^4.16.3", 31 "webpack-cli": "^3.1.0" 32 } 33} 34
  • manifest.json

json

1{ 2 "manifest_version": 2, 3 "name": "AtCoder_Bookmark", 4 "version": "0.0.1", 5 "description": "AtCoderのリンクを保存します。", 6 "author": "ganariya", 7 "browser_action": { 8 "default_icon": { 9 "19": "images/small_icon.png", 10 "38": "images/large_icon.png" 11 } 12 }, 13 "content_scripts": [ 14 { 15 "js": [ 16 "scripts/third/jquery-3.3.1.min.js", 17 "scripts/atcoder.bundle.js" 18 ], 19 "matches": [ 20 "https://beta.atcoder.jp/contests/*/tasks", 21 "https://*.contest.atcoder.jp/assignments" 22 ] 23 } 24 ], 25 "background": { 26 "scripts": [ 27 "scripts/background.bundle.js" 28 ], 29 "persistent": false 30 }, 31 "permissions": [ 32 "http://beta.atcoder.jp/", 33 "storage", 34 "unlimitedStorage" 35 ]

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

質問1

連想配列で格納するのがいいと思います。
キーはURLあたりでしょうか。

質問2

StorageAreaのsetメソッドは2番目の引数にcallbackを持つので、
chrome.storage.local.set()が非同期で動いているからだと推測します。

自分が作っているChrome拡張では、以下のようにPromiseでラップして、
呼び出し元でawait ChromeStorage.set({...})のように同期的に呼び出しています。

chromestorage.js

1const ChromeStorage = { 2 get: async function (keys) { 3 return new Promise(resolve => { 4 chrome.storage.local.get(keys, resolve); 5 }); 6 }, 7 8 set: async function (items) { 9 return new Promise(resolve => { 10 chrome.storage.local.set(items, resolve); 11 }); 12 } 13};

投稿2018/08/14 02:42

ikemo

総合スコア332

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問