I am encountering a hard time to solve these 2 issues and still working on it. Hopefully someone can help me. Thanks in advance!
1.) I have a map.service with this function.
readKML(file): any {
const exportUrl = URL.createObjectURL(file);
const reader = new HERE_MAP.data.kml.Reader(exportUrl);
// Parse the document
reader.parse();
reader.addEventListener('statechange', (evt) => {
if (evt.state === HERE_MAP.data.AbstractReader.State.READY) {
return of({
markers: ['test'],
lines: ['test]
});
}
if (evt.state === HERE_MAP.data.AbstractReader.State.ERROR) {
this.message.error('KML parsing error');
return of(null);
}
});
}
This function is being called in the component and expect to get the return data.
this.map.service.readKML(file)
.subscribe(
data => {
console.log(data);
}
)
The problem is im getting an error
this.map.readKML(...).subscribe is not a function
Expectation:
The data should received if the stateChange is equal to 'READY'.
2.) The service will be called at the same time with different param value and expected to have different returns if number 1 is okay.
However, this can be solved if 1 is still be an issue.
this.map.service.readKML(file1)
.subscribe(
data => {
console.log('one', data);
}
)
this.map.service.readKML(file1)
.subscribe(
data => {
console.log('two', data);
}
)
If you guys have an idea on how to fix this or other approach much appreciated. Thanks!
Issue: First why your code failed:
addEventListener is an async operation and is returning void because of is not even reached by the time your function has already returned from readKML.
readKML(file): any {
const exportUrl = URL.createObjectURL(file);
const reader = new HERE_MAP.data.kml.Reader(exportUrl);
// Parse the document
reader.parse();
// 'addEventListener' is an async operation which returns void, so you are returning a void
reader.addEventListener('statechange', (evt) => {
if (evt.state === HERE_MAP.data.AbstractReader.State.READY) {
return of({ // reached here after already returning void
markers: ['test'],
lines: ['test']
});
}
if (evt.state === HERE_MAP.data.AbstractReader.State.ERROR) {
this.message.error('KML parsing error');
return of(null);
}
});
}
Fix: you need to return an observable. So wrap the addEventListener into an observable. Complete the observable once the response comes.
Since you are returning observable, every time that you call this readKML method a new observable would be created.
readKML(file): any {
const exportUrl = URL.createObjectURL(file);
const reader = new HERE_MAP.data.kml.Reader(exportUrl);
reader.parse();
return new Observable((subscriber) => { // return observable
reader.addEventListener('statechange', (evt) => {
if (evt.state === HERE_MAP.data.AbstractReader.State.READY) {
subscriber.next({
markers: ['test'],
lines: ['test']
}); // return response
subscriber.complete(); // always complete for next so only single reponse goes for single method call (cold observable)
}
if (evt.state === HERE_MAP.data.AbstractReader.State.ERROR) {
this.message.error('KML parsing error');
subscriber.next(null); // you can also throw error ` throw throwError(response); `;
subscriber.complete();
}
});
});
}