【问题标题】:Angular2/Nativescript: Issues converting a service that used to use LocalStorage to one that uses nativescript-application/settingsAngular2/Nativescript:将使用 LocalStorage 的服务转换为使用 nativescript-application/settings 的服务的问题
【发布时间】:2017-01-06 07:25:13
【问题描述】:

我正忙于一个简单的条形码扫描仪应用程序,并试图将之前在 Web 应用程序中使用 LocalStorage 的服务转换为使用应用程序设置来保存本地 IP。该应用程序构建良好,但是当它部署到 genymotion 模拟器时,我收到以下错误。知道为什么会发生这种情况吗? 所以看起来问题出在应用程序设置的 getString 和/或 setString 方法上。我从使用 LocalStorage 的 Web 应用程序中复制了一项服务,并用 appSettings 替换了 localStorage,用 getString 和 setString 替换了 getItem……我在 Nativescript 的 getString 和 setString 中遗漏了什么吗?我认为它的工作方式与 LocalStorage 浏览器 API 完全相同...

我的错误:

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.

我的 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']);
        }
}

我的 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() { }
}

【问题讨论】:

  • Unexpected token u in JSON at position 0 指的是格式错误的 json。它似乎连接到findLocalIP。我会在那里开始调查。
  • @AJT_82 奇怪的是我还没有设置任何 ip。在我的 AppSettingsService 中,我检查了何时尚未设置 IP,因此不确定它可以从哪里获取此 U...
  • 现在答案已编辑,现在它应该可以工作了,它不是很漂亮,但应该可以工作。

标签: angular angular2-nativescript


【解决方案1】:

您的ngOnInit 正在调用服务中的findLocalIP() 方法,这就是发生错误的地方。

您的问题应该在以下行:

let data = JSON.parse(appSettings.getString('retail_mobile'));

它试图解析一些不可解析的东西。

这里的问题似乎是不匹配。 appSettings.getString 正在返回一个字符串,因此无法对其进行解析。通过删除 JSON.parse 应该可以清除问题。

let data = appSettings.getString('retail_mobile')

如果你想/需要使用 JSON,我希望你必须将它实际转换为 json 并以某种方式返回,例如如下所示。它不漂亮,但应该可以。

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;
   }

只是以字符串/json为例:

retail_mobile = "{ something: "something" }" 这可能看起来像 JSON,但它不是,它是一个字符串。

如果您尝试console.log(JSON.parse(retail_mobile)),它会抛出您遇到的错误。

在解析之前,您实际上必须JSON.stringify 它,因此按此顺序执行以下命令不会产生错误:

retail_mobile = "{ something: "something" }"
let data = JSON.stringify(retail_mobile); 
console.log(JSON.parse(data));

作为对您指出错误指向 .js 文件的评论。在运行时 TS 被编译为 JS,所以它不知道也不关心 TS-files,因此错误指向 JS-files。

【讨论】:

  • 感谢您的浏览。我在 getLocalIP 函数的顶部添加了以下内容:console.log(JSON.parse(appSettings.getString('retail_mobile')));我没有看到任何内容被记录到 Windows 命令提示符?这在网络应用程序中运行良好,所以它必须是特定于应用程序设置的东西?我对该服务所做的只是将 localService 替换为 appSettings 并将 getItem 替换为 getString 以尝试使其与 Nativescript 一起使用...
  • 您正在检查您的服务方法中的 null,所以如果没有设置 ip,appSettings.getString('retail_mobile‌​')) 不应该返回 null,对吧?如果它没有记录任何东西,那就有问题了。
  • let data = appSettings.getString('retail_mobile‌')) 如果 data 为 null 则返回 null (在该语句下方有一个 if 语句进行检查?难道是错误发生在控制台之前.log 已到达?
  • 感谢非常详细的解释。我现在可以记录存储在那里的值。它是未定义的,所以不应该为空吗?无论首先获取值然后对其进行字符串化然后对其进行解析,我仍然会遇到相同的错误......
  • 再次感谢@AJT_82 的耐心/努力。我从来没有见过任何人在这里付出如此多的努力来帮助/解释发生了什么......现在它工作得很好!:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多