合并 angular 中的两个 observable 以将 CSV 转换为 JSON
Merge two observables in angular for CSV to JSON conversion
我有一个 csv
文件,我想将它转换成 JSON
。
我正在使用 HttpClient
读取 CSV 文件,然后使用 csvToJson 对其进行转换。
此测试代码有效:
this.httpClient
.get('assets/csv/results.csv', { responseType: 'text' })
.subscribe(
(data) => {
csv()
.fromString(data)
.subscribe((jsonObj) => console.log(jsonObj));
}
);
但是当我尝试合并这两个 observable 来创建一个函数时:
convert() {
this.httpClient
.get('assets/csv/results.csv', { responseType: 'text' })
.pipe(switchMap((d) => csv().fromString(d)))
.subscribe((c) => console.dir(c));
}
我收到这个错误:
core.js:4352 ERROR TypeError: You provided an invalid object where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.
at subscribeTo (subscribeTo.js:27)
at innerSubscribe (innerSubscribe.js:69)
at SwitchMapSubscriber._innerSub (switchMap.js:44)
at SwitchMapSubscriber._next (switchMap.js:34)
at SwitchMapSubscriber.next (Subscriber.js:49)
at MapSubscriber._next (map.js:35)
at MapSubscriber.next (Subscriber.js:49)
at FilterSubscriber._next (filter.js:33)
at FilterSubscriber.next (Subscriber.js:49)
at MergeMapSubscriber.notifyNext (mergeMap.js:70)
at SimpleInnerSubscriber._next (innerSubscribe.js:10)
at SimpleInnerSubscriber.next (Subscriber.js:49)
at XMLHttpRequest.onLoad (http.js:1678)
at ZoneDelegate.invokeTask (zone-evergreen.js:399)
at Object.onInvokeTask (core.js:27474)
at ZoneDelegate.invokeTask (zone-evergreen.js:398)
更新
我创建了一个 stackblitz 来进行实验。
在 stackblitz 中我得到一个错误,我没有进入本地主机:
Error in src/app/csv-2-json.service.ts (18:24)
This expression is not callable.
Type '{ default: (param?: Partial<CSVParseParam>, options?: any) => Converter; }' has no call signatures.
在实现 PromiseLike<any[]>
的库 source code I see that the fromString()
returns a Converter 中,所以我认为它应该可以工作。
我做错了什么?
错误
如果我们阅读错误消息,则以下部分是必不可少的:您在需要流的位置提供了无效对象
说明
您的代码 return 是 object
在您的 pipe
中的某处,而应该是 observable
。我希望这会发生在您的 switchMap
中。我没有使用给定的库,但我希望 csv().fromString(d)
到 return 一个对象而不是一个可观察的对象。
解决方案
如果您通过 of.
将 object
更改为 observable
,我希望您的代码能够正常工作
switchMap(d => of(csv().fromString(d)))
可能更好的解决方案
在我看来,switchMap
在你的案例中是无稽之谈。
1. 如果你想坚持上面的代码,你可以使用 map 代替:
map(d => csv().fromString(d))
2. 如果你想合并所有以前传入的数据,使用scan 来累积所有以前的值。之后您可以对所有以前的数据使用 map
scan((acc, curr) => ([...acc, ...curr]), [])
// I don't know how to accumulate your data as I did not work with the library. I now pushed all the values to an array
我认为问题在于 csvtojson
包。
首先,如果您通过 import * as csv from "csvtojson"
导入它,您在 csv
变量中得到的是一个具有 4 个属性的对象,'csv' 'Converter' 和'default',每一个都指向一个函数。因此,您在 stackblitz 中遇到的错误 Type '{ default: (param?: Partial<CSVParseParam>, options?: any) => Converter; }' has no call signatures.
意味着您正在尝试将对象视为函数并调用它。但是您不能在 Javascript.
中调用对象
您可以通过从 csv' Object, like this
const csvFunc = csv["csv"]. Now in
csvFunc 中检索 'csv' 函数来向前迈出一步,您有一个函数可以调用。
但此时我们进入另一个问题。如果我们做 const csvInvocationResult = csvFunc().fromString(d)
我们得到的不是标准的 Promise
,而是一个接受 then
方法的对象,就像一个普通的 Promise。因此 Object.getPrototypeOf.then(jsonFroCsv => // do something)
实际上有效。
不幸的是,在 Stackbliz 中我无法浏览原型链(我在尝试执行 Object.getPrototypeOf
时遇到错误)所以我不知道这个对象从哪里继承。无论如何,不是真正的 Promise,switchMap
运算符不起作用。
我建议你深入研究 csvtojson
库,看看它是如何工作的,看看你是否可以将它调整为 return 一个真正的 Promise 或者找到一种方法来转换它的结果 return真正的承诺。
此回答无法解决您的问题,但我希望对您有所帮助。
我有一个 csv
文件,我想将它转换成 JSON
。
我正在使用 HttpClient
读取 CSV 文件,然后使用 csvToJson 对其进行转换。
此测试代码有效:
this.httpClient
.get('assets/csv/results.csv', { responseType: 'text' })
.subscribe(
(data) => {
csv()
.fromString(data)
.subscribe((jsonObj) => console.log(jsonObj));
}
);
但是当我尝试合并这两个 observable 来创建一个函数时:
convert() {
this.httpClient
.get('assets/csv/results.csv', { responseType: 'text' })
.pipe(switchMap((d) => csv().fromString(d)))
.subscribe((c) => console.dir(c));
}
我收到这个错误:
core.js:4352 ERROR TypeError: You provided an invalid object where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.
at subscribeTo (subscribeTo.js:27)
at innerSubscribe (innerSubscribe.js:69)
at SwitchMapSubscriber._innerSub (switchMap.js:44)
at SwitchMapSubscriber._next (switchMap.js:34)
at SwitchMapSubscriber.next (Subscriber.js:49)
at MapSubscriber._next (map.js:35)
at MapSubscriber.next (Subscriber.js:49)
at FilterSubscriber._next (filter.js:33)
at FilterSubscriber.next (Subscriber.js:49)
at MergeMapSubscriber.notifyNext (mergeMap.js:70)
at SimpleInnerSubscriber._next (innerSubscribe.js:10)
at SimpleInnerSubscriber.next (Subscriber.js:49)
at XMLHttpRequest.onLoad (http.js:1678)
at ZoneDelegate.invokeTask (zone-evergreen.js:399)
at Object.onInvokeTask (core.js:27474)
at ZoneDelegate.invokeTask (zone-evergreen.js:398)
更新
我创建了一个 stackblitz 来进行实验。
在 stackblitz 中我得到一个错误,我没有进入本地主机:
Error in src/app/csv-2-json.service.ts (18:24)
This expression is not callable.
Type '{ default: (param?: Partial<CSVParseParam>, options?: any) => Converter; }' has no call signatures.
在实现 PromiseLike<any[]>
的库 source code I see that the fromString()
returns a Converter 中,所以我认为它应该可以工作。
我做错了什么?
错误
如果我们阅读错误消息,则以下部分是必不可少的:您在需要流的位置提供了无效对象
说明
您的代码 return 是 object
在您的 pipe
中的某处,而应该是 observable
。我希望这会发生在您的 switchMap
中。我没有使用给定的库,但我希望 csv().fromString(d)
到 return 一个对象而不是一个可观察的对象。
解决方案
如果您通过 of.
将object
更改为 observable
,我希望您的代码能够正常工作
switchMap(d => of(csv().fromString(d)))
可能更好的解决方案
在我看来,switchMap
在你的案例中是无稽之谈。
1. 如果你想坚持上面的代码,你可以使用 map 代替:
map(d => csv().fromString(d))
2. 如果你想合并所有以前传入的数据,使用scan 来累积所有以前的值。之后您可以对所有以前的数据使用 map
scan((acc, curr) => ([...acc, ...curr]), [])
// I don't know how to accumulate your data as I did not work with the library. I now pushed all the values to an array
我认为问题在于 csvtojson
包。
首先,如果您通过 import * as csv from "csvtojson"
导入它,您在 csv
变量中得到的是一个具有 4 个属性的对象,'csv' 'Converter' 和'default',每一个都指向一个函数。因此,您在 stackblitz 中遇到的错误 Type '{ default: (param?: Partial<CSVParseParam>, options?: any) => Converter; }' has no call signatures.
意味着您正在尝试将对象视为函数并调用它。但是您不能在 Javascript.
您可以通过从 csv' Object, like this
const csvFunc = csv["csv"]. Now in
csvFunc 中检索 'csv' 函数来向前迈出一步,您有一个函数可以调用。
但此时我们进入另一个问题。如果我们做 const csvInvocationResult = csvFunc().fromString(d)
我们得到的不是标准的 Promise
,而是一个接受 then
方法的对象,就像一个普通的 Promise。因此 Object.getPrototypeOf.then(jsonFroCsv => // do something)
实际上有效。
不幸的是,在 Stackbliz 中我无法浏览原型链(我在尝试执行 Object.getPrototypeOf
时遇到错误)所以我不知道这个对象从哪里继承。无论如何,不是真正的 Promise,switchMap
运算符不起作用。
我建议你深入研究 csvtojson
库,看看它是如何工作的,看看你是否可以将它调整为 return 一个真正的 Promise 或者找到一种方法来转换它的结果 return真正的承诺。
此回答无法解决您的问题,但我希望对您有所帮助。