Issue
I'm pretty sure it's my fault, but I can't spot it.
I created a new Ionic/Angular app with ionic start oracolo
and then I added a new component to it (named Histogram, though that does not really matter). Then I installed vega-embed with npm install vega-embed
and tried to add a Vega/Vega-Lite view into my component using this code:
async ngOnInit() {
const spec = "https://raw.githubusercontent.com/vega/vega/master/docs/examples/bar-chart.vg.json";
const result = await embed("figure#vis", spec);
console.log(result.view);
}
paired with its HTML template:
<div>
<figure id="vis"></figure>
</div>
I think what I have done here is just follow the example code on the vega-embed project page, however when I run my app no Vega view appears and I get the following error in my browser console:
Uncaught (in promise): Error: figure#vis does not exist
Error: figure#vis does not exist
at _callee4$ (vega-embed.module.js:2960:17)
at tryCatch (vega-embed.module.js:123:15)
at Generator.invoke [as _invoke] (vega-embed.module.js:319:20)
at prototype.<computed> [as next] (vega-embed.module.js:172:19)
at asyncGeneratorStep (vega-embed.module.js:54:24)
at _next (vega-embed.module.js:73:9)
at vega-embed.module.js:78:7
at new ZoneAwarePromise (zone.js:1429:21)
at vega-embed.module.js:70:12
at _embed3 (vega-embed.module.js:3227:18)
at resolvePromise (zone.js:1211:31)
at zone.js:1118:17
at zone.js:1134:33
at rejected (tslib.es6.js:119:89)
at _ZoneDelegate.invoke (zone.js:372:26)
at Object.onInvoke (core.mjs:24313:33)
at _ZoneDelegate.invoke (zone.js:371:52)
at Zone.run (zone.js:134:43)
at zone.js:1275:36
at _ZoneDelegate.invokeTask (zone.js:406:31)
I'm not sure if the app being a Ionic app could make any difference from the vega-embed point of view, so I brought it to you as is. What am I doing wrong?
EDITED after E.Maggini's answer:
I've tried moving the code to ngAfterViewInit
, where the DOM is supposedly available, but I'm getting the same error:
export class HistogramComponent implements OnInit, AfterViewInit {
constructor() { }
ngOnInit() { }
async ngAfterViewInit() {
const spec = "https://raw.githubusercontent.com/vega/vega/master/docs/examples/bar-chart.vg.json";
const result = await embed("figure#vis", spec);
console.log(result.view);
}
}
EDIT 2:
Adding the Vega view to the pre-existing ExploreContainerComponent that was autogenerated by the ionic start
command DOES work. Adding the view to the HistogramComponent I generated afterwards does NOT work.
However I can't see any differences between the two components, except their name.
Solution
In the end the problem was totally unrelated to vega-embed
, but was being caused by a mistake in how I was including my custom component into the tab, and this code wasn't shown in my question:
tab3.page.html
, before I found the mistake:
<app-explore-container name="Tab 3 page">
<histogram></histogram>
</app-explore-container>
tab3.page.html
, after the fix:
<app-explore-container name="Tab 3 page">
</app-explore-container>
<histogram></histogram>
Problem here is that app-explore-container
is a custom component that does not support projected content (it lacks ng-content
in its template), so nesting anything into it while in an external template (tab3.page.html
) won't work.
The same goes for any custom component I created so far in my life, but for some weird reason I instinctively nested my histogram
into app-explore-container
taking for granted it would have behaved just like any other HTML tag.
With reference to E.Maggini's answer, I even tried moving the code back into ngOnInit
and it does work, so while this was actually a lifecycle issue as suggeted, because projected content issues are such, and while it's likely true that the DOM isn't available during the OnInit
phase, I guess that does not make any difference, because of the async nature of the embed
function, which is not executing its code during ngOnInit
, but as soon as it can.
Answered By - Lucio Crusca
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.