I am busy with a simple barcode scanner app and trying to convert a service which used LocalStorage in a web app before to use application-settings to save a local IP. The app builds fine but when it gets deployed to a genymotion emulator I get the following error. Any idea why this might be happening? So it seems like the issue is with the getString and/or setString methods of application-settings. I coppyed a service from a web app which used LocalStorage and replaced localStorage with appSettings and getItem with getString and setString... Am i missing something in Nativescript's getString and setString? I thought it works the exact same way as the LocalStorage browser API...
my error:
JS: EXCEPTION: Error in ./AppComponent class AppComponent_Host - inline template:0:0 caused by: Unexpected token u in JSON at position 0
JS: ORIGINAL EXCEPTION: Unexpected token u in JSON at position 0
JS: ORIGINAL STACKTRACE:
JS: SyntaxError: Unexpected token u in JSON at position 0
JS: at Object.parse (native)
JS: at AppSettingsService.findLocalIP (/data/data/org.nativescript.barcodescanner/files/app/services/app-settings.service.js:19:25)
JS: at AppComponent.ngOnInit (/data/data/org.nativescript.barcodescanner/files/app/app.component.js:13:42)
JS: at Wrapper_AppComponent.detectChangesInInputProps (/AppModule/AppComponent/wrapper.ngfactory.js:18:53)
JS: at DebugAppView._View_AppComponent_Host0.detectChangesInternal (/AppModule/AppComponent/host.ngfactory.js:30:26)
JS: at DebugAppView.AppView.detectChanges (/data/data/org.nativescript.barcodescanner/files/app/tns_modules/@angular/core/bundles/core.umd.js:9305:18)
JS: at DebugAppView.detectChanges (/data/data/org.nativescript.barcodescanner/files/app/tns_modules/@angular/core/bundles/core.umd.js:9410:48)
JS: at ViewRef_.detectChanges (/data/data/org.nativescript.barcodescanner/files/app/tns_modules/@angular/core/bundles/core.umd.js:7398:24)
JS: at /data/data/org.nativescript.barcodescanner/files/app/tns_modules/@angular/core/bundles/core.umd.js:6819:88
JS: at Array.forEach (native)
JS: ERROR CONTEXT:
JS: [object Object]
JS: ns-renderer: ERROR BOOTSTRAPPING ANGULAR
JS: ns-renderer: Error in ./AppComponent class AppComponent_Host - inline template:0:0 caused by: Unexpected token u in JSON at position 0
JS:
JS: SyntaxError: Unexpected token u in JSON at position 0
JS: at Object.parse (native)
JS: at AppSettingsService.findLocalIP (/data/data/org.nativescript.barcodescanner/files/app/services/app-settings.service.js:19:25)
JS: at AppComponent.ngOnInit (/data/data/org.nativescript.barcodescanner/files/app/app.component.js:13:42)
JS: at Wrapper_AppComponent.detectChangesInInputProps (/AppModule/AppComponent/wrapper.ngfactory.js:18:53)
JS: at DebugAppView._View_AppComponent_Host0.detectChangesInternal (/AppModule/AppComponent/host.ngfactory.js:30:26)
JS: at DebugAppView.AppView.detectChanges (/data/data/org.nativescript.barcodescanner/files/app/tns_modules/@angular/core/bundles/core.umd.js:9305:18)
JS: at DebugAppView.detectChanges (/data/data/org.nativescript.barcodescanner/files/app/tns_modules/@angular/core/bundles/core.umd.js:9410:48)
JS: at ViewRef_.detectChanges (/data/data/org.nativescript.barcodescanner/files/app/tns_modules/@angular/core/bundles/core.umd.js:7398:24)
JS: at /data/data/org.nativescript.barcodescanner/files/app/tns_modules/@angular/core/bundles/core.umd.js:6819:88
JS: at Array.forEach (native)
8:46:00 AM - Compilation complete. Watching for file changes.
my app.component.ts:
import { Component, OnInit } from "@angular/core";
import { RouterExtensions } from 'nativescript-angular/router';
import { RestService } from './services/rest.service';
import { AppSettingsService } from './services/app-settings.service';
@Component({
selector: "main",
template : "<page-router-outlet></page-router-outlet>"
})
export class AppComponent implements OnInit {
constructor(private restService: RestService, private appSettingsService: AppSettingsService, private routerExtensions: RouterExtensions) {
}
ngOnInit() {
let ip = this.appSettingsService.findLocalIP();
if (ip !== null) {
this.restService.init(ip);
} else if (ip === null) {
this.routerExtensions.navigate(['settings']);
}
}
my app-settings.service:
import { Injectable } from '@angular/core';
import * as appSettings from 'application-settings';
@Injectable()
export class AppSettingsService {
saveLocalIP(ip: string): void {
let localData = appSettings.getString('retail_mobile');
if (localData) {
localData = JSON.parse(localData);
} else {
localData = "";
}
let saveData = {localIP:ip};
appSettings.setString('retail_mobile', JSON.stringify(saveData));
}
findLocalIP() {
let data = JSON.parse(appSettings.getString('retail_mobile'));
if (data === null) {
console.log("No entry found in local storage...");
return null;
}
if(data && !data.localIP) {
console.log("no local ip found in localStorage...")
return null;
}
return data.localIP;
}
constructor() { }
}
Your ngOnInit
is calling the method findLocalIP()
in the service, and that's where the error happens.
Your problem should be in the following line:
let data = JSON.parse(appSettings.getString('retail_mobile'));
It's trying to parse something that is not parsable.
The problem here seems to be the mismatch. appSettings.getString
is returning a string, therefore it cannot be parsed. By removing JSON.parse
that should clear things out.
let data = appSettings.getString('retail_mobile')
If you want/need to use use JSON, which I would expect, you have to actually convert it to json and back somehow, e.g like below. It's not pretty, but should work.
findLocalIP() {
let d = appSettings.getString('retail_mobile'); // add
let d1 = JSON.stringify(d); // make it json
let data = JSON.parse(d1); // now parse it
if (data === null) {
console.log("No entry found in local storage...");
return null;
}
Just to set an example with string/json:
retail_mobile = "{ something: "something" }"
This might look like JSON, but it is not, it's a string.
If you try console.log(JSON.parse(retail_mobile))
it will throw you that error that you have.
BEFORE parsing you actually have to JSON.stringify
it, so the following commands in this order would not produce an error:
retail_mobile = "{ something: "something" }"
let data = JSON.stringify(retail_mobile);
console.log(JSON.parse(data));
And as a comment to you for referring that the errors point to .js-files. At runtime TS is compiled as JS, so it doesn't know or care about TS-files, therefore errors point to JS-files.