· 9 years ago · Oct 23, 2016, 05:30 PM
1EXCEPTION: Error in ./AppRoot class AppRoot_Host - inline template:0:0 app.bundle.js:44905
2EXCEPTION: Error in ./AppRoot class AppRoot_Host - inline template:0:0 app.bundle.js:44896
3ORIGINAL EXCEPTION: Can't resolve all parameters for ChatsStorageService: (?). app.bundle.js:44896
4ORIGINAL STACKTRACE: app.bundle.js:44896
5Error: Can't resolve all parameters for ChatsStorageService: (?).
6 at new BaseException (file:///android_asset/www/build/js/app.bundle.js:25523:24)
7 at CompileMetadataResolver.getDependenciesMetadata (file:///android_asset/www/build/js/app.bundle.js:38037:20)
8 at CompileMetadataResolver.getTypeMetadata (file:///android_asset/www/build/js/app.bundle.js:37918:27)
9 at file:///android_asset/www/build/js/app.bundle.js:38072:31
10 at Array.map (native)
11 at Object.Call (file:///android_asset/www/build/js/es6-shim.min.js:10:4652)
12 at Array.map (file:///android_asset/www/build/js/es6-shim.min.js:10:19780)
13 at CompileMetadataResolver.getProvidersMetadata (file:///android_asset/www/build/js/app.bundle.js:38060:27)
14 at CompileMetadataResolver.getDirectiveMetadata (file:///android_asset/www/build/js/app.bundle.js:37868:35)
15 at RuntimeCompiler._getCompiledHostTemplate (file:///android_asset/www/build/js/app.bundle.js:36412:52)
16
17import { Injectable } from "@angular/core";
18import { SQLite } from 'ionic-native';
19import { Chat, Message } from 'api/models';
20import { Messages } from 'api/collections';
21import { SqlDatabase } from './SqlDatabase';
22import { isBrowser } from './platform';
23import { SqlResultSet } from './SqlResultSet';
24
25@Injectable()
26export class ChatsStorageService {
27
28 private database = null;
29 private databaseName: string = 'data.db.thewhozoo';
30 public chats: Array<Chat> = new Array<Chat>();
31 public messages: Array<Message> = new Array<Message>();
32
33
34 private dbPromise: Promise<SqlDatabase>;
35
36 constructor(private _db: any) {
37 }
38
39 public createDatabase(): void {
40 const createChatsTable: string = "CREATE TABLE IF NOT EXISTS chats (_id TEXT PRIMARY KEY, memberIds TEXT, title TEXT, subTitle TEXT, picture TEXT, lastMessageId TEXT, lastMessageCreatedAt DATE)";
41 const createMessagesTable: string = "CREATE TABLE IF NOT EXISTS messages (_id TEXT PRIMARY KEY, chatId TEXT, senderId TEXT, ownership TEXT, content TEXT, createdAt DATE, changeDate BOOLEAN, readByReceiver BOOLEAN)";
42 this.dbPromise = SqlDatabase.open(this.databaseName, [createChatsTable, createMessagesTable]);
43 this.dbPromise.then((data) => {
44 console.log('database ' + this.databaseName + ' created');
45 });
46 }
47
48 public refreshChats(): Promise<any> {
49 const statement: string = "SELECT * FROM chats";
50 return this.dbPromise
51 .then((db) => db.execute(statement))
52 .then((resultSet) => {
53 this.chats = [];
54 if (resultSet.rows.length > 0) {
55 for (var i = 0; i < resultSet.rows.length; i++) {
56 this.populateChat(resultSet.rows.item(i));
57 }
58 }
59 });
60 }
61
62 private populateChat(chatItem: any): Promise<any> {
63 const statement: string = "SELECT * FROM messages where _id = ?";
64 const params: string[] = [chatItem.lastMessageId];
65 let messages: Array<Message> = new Array<Message>();
66 return this.dbPromise
67 .then((db) => db.execute(statement, params))
68 .then((messageData) => {
69 this.chats = [];
70 if (messageData.rows.length > 0) {
71 for (var j = 0; j < messageData.rows.length; j++) {
72 if (messageData.rows.item(j)) {
73 let messageValue: Message = { _id: messageData.rows.item(j)._id, chatId: messageData.rows.item(j).chatId, senderId: messageData.rows.item(j).senderId, ownership: messageData.rows.item(j).ownership, content: messageData.rows.item(j).content, createdAt: messageData.rows.item(j).createdAt, changeDate: messageData.rows.item(j).changeDate, readByReceiver: messageData.rows.item(j).readByReceiver };
74 messages.push(messageValue);
75 }
76 }
77 }
78 let chatValue: Chat = {
79 _id: chatItem._id, memberIds: chatItem.memberIds, title: chatItem.title, subTitle: chatItem.subTitle,
80 picture: chatItem.picture, lastMessage: messages[0], lastMessageCreatedAt: chatItem.lastMessageCreatedAt
81 };
82 if (this.chats.indexOf(chatValue) === -1) {
83 this.chats.push(chatValue);
84 }
85 });
86 }
87
88 public refreshMessages(): Promise<any> {
89 const statement: string = "SELECT * FROM messages";
90 return this.dbPromise
91 .then((db) => db.execute(statement))
92 .then((resultSet) => {
93 this.messages = [];
94 if (resultSet.rows.length > 0) {
95 for (var i = 0; i < resultSet.rows.length; i++) {
96 if (resultSet.rows.item(i)) {
97 this.messages.push({ _id: resultSet.rows.item(i)._id, chatId: resultSet.rows.item(i).chatId, senderId: resultSet.rows.item(i).senderId, ownership: resultSet.rows.item(i).ownership, content: resultSet.rows.item(i).content, createdAt: resultSet.rows.item(i).createdAt, changeDate: resultSet.rows.item(i).changeDate, readByReceiver: resultSet.rows.item(i).readByReceiver });
98 }
99 }
100 }
101 });
102 }
103
104 public addChat(chat: Chat): Promise<any> {
105 if (window.cordova) {
106 if (this.chats.indexOf(chat) < 0) {
107 const statement: string = "INSERT INTO chats (_id, memberIds, title, subTitle, picture, lastMessageId, lastMessageCreatedAt) VALUES (?, ?, ?, ?, ?, ?, ?)";
108 const params: any[] = [chat._id, chat.memberIds, chat.title, chat.subTitle, chat.picture, chat.lastMessage._id, chat.lastMessageCreatedAt];
109 this.chats.push(chat);
110 return this.dbPromise
111 .then((db) => db.execute(statement, params))
112 .then((resultSet) => {
113 console.log('added chat: ', resultSet);
114 });
115 }
116 }
117 }
118
119 public updateChat(chat: Chat): Promise<any> {
120 if (window.cordova) {
121 let idx: number = this.contains(this.chats, chat);
122 if (idx >= 0) {
123 this.chats[idx] = chat;
124 const statement: string = "UPDATE chats SET memberIds = ?, title = ?, subTitle = ?, picture = ?, lastMessageId = ?, lastMessageCreatedAt = ? WHERE _id = ?"
125 const params: any[] = [chat.memberIds, chat.title, chat.subTitle, chat.picture, chat.lastMessage._id, chat.lastMessageCreatedAt, chat._id];
126 return this.dbPromise
127 .then((db) => db.execute(statement, params))
128 .then((resultSet) => {
129 console.log('updated chat: ', resultSet);
130 });
131 }
132 }
133 }
134
135 public updateMessage(message: Message): Promise<any> {
136 if (window.cordova) {
137 let idx: number = this.contains(this.messages, message);
138 if (idx >= 0) {
139 this.messages[idx] = message;
140 const statement: string = "UPDATE messages SET readByReceiver = ? WHERE _id = ?";
141 const params: any[] = [message.readByReceiver, message._id];
142 return this.dbPromise
143 .then((db) => db.execute(statement, params))
144 .then((resultSet) => {
145 console.log('updated message: ', resultSet);
146 });
147 }
148 }
149 }
150
151 private contains(arr: Array<any>, obje: any): number {
152 for (let i: number = 0; i < arr.length; i++) {
153 if (arr[i]._id === obje._id) {
154 return i;
155 }
156 }
157 return -1;
158 }
159
160 public removeChat(chat: Chat): Promise<any> {
161 if (window.cordova) {
162 let idx: number = this.chats.indexOf(chat);
163 if (idx >= 0) {
164 const selectStatement: string = "SELECT * FROM chats where _id = ?";
165 const selectParams: string[] = [chat._id];
166 const deleteStatement: string = "DELETE FROM chats where _id = ?";
167 const deleteParams: string[] = [chat._id];
168 for (let i: number = 0; i < this.messages.length; i++) {
169 if (this.messages[i].chatId === chat._id) {
170 this.removeMessage(this.messages[i]);
171 }
172 }
173 this.chats.splice(idx, 1);
174 return this.dbPromise
175 .then((db) => db.execute(selectStatement, selectParams))
176 .then((resultSet) => {
177 if (resultSet && resultSet.rows.length > 0) {
178 return this.dbPromise
179 .then((db) => db.execute(deleteStatement, deleteParams))
180 .then((resultSet) => {
181 console.log('chat deleted: ', resultSet);
182 });
183 }
184 });
185 }
186 }
187 }
188
189 public addMessage(chat: Chat, message: Message): Promise<Message> {
190 let promise: Promise<Message> = new Promise<Message>(resolve => {
191 if (window.cordova) {
192 const statement: string = "SELECT * FROM chats where _id = ?";
193 const params: string[] = [chat._id];
194 return this.dbPromise
195 .then((db) => db.execute(statement, params))
196 .then((resultSet) => {
197 if (!resultSet || resultSet.rows.length === 0) {
198 this.addChat(chat);
199 }
200 if (this.messages.indexOf(message) < 0) {
201 this.addTheMessage(message);
202 }
203 });
204 }
205 });
206 return promise;
207 }
208
209 private addTheMessage(message: Message): Promise<any> {
210 const selectStatement: string = "SELECT * FROM messages where _id = ?";
211 const selectParams: string[] = [message._id];
212 const insertStatement: string = "INSERT INTO messages (_id, chatId, senderId, ownership, content, createdAt, changeDate, readByReceiver) VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
213 const insterParams: any[] = [message._id, message.chatId, message.senderId, message.ownership, message.content, message.createdAt, message.changeDate, message.readByReceiver];
214 return this.dbPromise
215 .then((db) => db.execute(selectStatement, selectParams))
216 .then((resultSet) => {
217 if (!resultSet || resultSet.rows.length === 0) {
218 return this.dbPromise
219 .then((db) => db.execute(insertStatement, insterParams))
220 .then((resultSet) => {
221 if (!resultSet || resultSet.rows.length === 0) {
222 let length: number = this.messages.push(message);
223 console.log('message inserted: ' + length, message);
224 }
225 });
226 }
227 });
228 }
229
230 public removeMessage(message: Message): Promise<any> {
231 if (window.cordova) {
232 let idx: number = this.messages.indexOf(message);
233 if (idx >= 0) {
234 const selectStatement: string = "SELECT * FROM messages where _id = ?";
235 const selectParams: string[] = [message._id];
236 const deleteStatement: string = "DELETE FROM messages where _id = ?";
237 const deleteParams: string[] = [message._id];
238 this.messages.splice(idx, 1);
239 return this.dbPromise
240 .then((db) => db.execute(selectStatement, selectParams))
241 .then((resultSet) => {
242 if (resultSet && resultSet.rows.length > 0) {
243 return this.dbPromise
244 .then((db) => db.execute(deleteStatement, deleteParams))
245 .then((resultSet) => {
246 console.log('message deleted: ', message);
247 });
248 }
249 });
250 }
251 }
252 }
253
254 public findLastMessageForChat(chat: Chat): Promise<Message> {
255 let promise: Promise<Message> = new Promise<Message>(resolve => {
256 const statement: string = "SELECT * FROM messages where chatId = ? order by createdAt desc";
257 const params: string[] = [chat._id];
258 return this.dbPromise
259 .then((db) => db.execute(statement, params))
260 .then((data) => {
261 let message: Message = null;
262 if (data.rows.length > 0) {
263 for (var i = 0; i < data.rows.length; i++) {
264 if (data.rows.item(i)) {
265 message = ({ _id: data.rows.item(i)._id, chatId: data.rows.item(i).chatId, senderId: data.rows.item(i).senderId, ownership: data.rows.item(i).ownership, content: data.rows.item(i).content, createdAt: data.rows.item(i).createdAt, changeDate: data.rows.item(i).changeDate, readByReceiver: data.rows.item(i).readByReceiver });
266 break;
267 }
268 }
269 }
270 resolve(message);
271 });
272 });
273 return promise;
274 }
275}
276
277import { isBrowser } from './platform';
278import { SqlResultSet } from './SqlResultSet';
279
280export class SqlDatabase {
281
282 constructor(private _db: any) { }
283
284 static open(name: string, initStatements: string[] = []): Promise<SqlDatabase> {
285 let dbPromise = isBrowser()
286 .then(browser => {
287 const openDatabase = browser ? openBrowserDatabase : openCordovaDatabase;
288 return openDatabase(name);
289 });
290 if (initStatements.length === 0) {
291 return dbPromise;
292 }
293 let _db: SqlDatabase;
294 // execute the first statement and capture the _db
295 dbPromise.then(db => {
296 _db = db;
297 return db.execute(initStatements.shift());
298 });
299 // execute all the other statements (if any) sequentially
300 for (let sql of initStatements) {
301 dbPromise.then(() => {
302 _db.execute(sql)
303 });
304 }
305 // resolve the _db only after all statements have completed
306 return new Promise((resolve, reject) => {
307 dbPromise.then(() => resolve(_db)).catch(reject);
308 });
309 }
310
311 execute(statement: string, params: any[] = []): Promise<SqlResultSet> {
312 return new Promise((resolve, reject) => {
313 this._db.transaction(tx => tx.executeSql(statement, params, (tx, resultSet) => {
314 resolve(resultSet);
315 }, (tx, error) => {
316 reject(error)
317 }));
318 });
319 }
320
321}
322
323declare var sqlitePlugin: any;
324
325function openCordovaDatabase(name: string): Promise<SqlDatabase> {
326 return new Promise((resolve, reject) => {
327 if (typeof sqlitePlugin === 'undefined') {
328 reject(new Error('[ionix-sqlite] sqlitePlugin global object not found; did you install a Cordova SQLite plugin?'));
329 }
330 const db = sqlitePlugin.openDatabase({
331 name: name,
332 location: 'default'
333 });
334 console.info('[ionix-sqlite] using Cordova sqlitePlugin');
335 resolve(new SqlDatabase(db));
336 });
337}
338
339declare function openDatabase(name: string, version: string, desc: string, size: number): any;
340
341function openBrowserDatabase(name: string): Promise<SqlDatabase> {
342 return new Promise((resolve, reject) => {
343 try {
344 const db = openDatabase(name, '1.0', name, -1);
345 console.info('[ionix-sqlite] using WebSQL');
346 resolve(new SqlDatabase(db));
347 } catch (error) {
348 reject(error);
349 }
350 });
351}
352
353declare var cordova;
354
355export function isBrowser(): Promise<boolean> {
356 if (typeof cordova === 'undefined') {
357 return Promise.resolve(true);
358 }
359 return new Promise(resolve => {
360 document.addEventListener('deviceready', () => {
361 resolve(cordova.platformId === 'browser');
362 });
363 });
364}
365
366import { SqlResultSetRows } from './SqlResultSetRows';
367
368export interface SqlResultSet {
369
370 insertId: number;
371 rowsAffected: number;
372 rows: SqlResultSetRows;
373
374}
375
376export interface SqlResultSetRows {
377
378 length: number;
379 item(index: number): any;
380
381}