0
votes

I'm building an SPA that can be described by the following image

enter image description here

Explanation: - An object items exists in the controller of the component2. - A user has the ability to manage this object by using the 4 different actions (buttons on the component1) - These actions (for the sake of simplicity) can refer to a different kind of plot. i.e When Action 1 is pressed, data inside items object can be plotted as a pie chart, when action 2 is chosen will be plotted as a histogram and so on. - These plots are going to appear in within the various ng-include templates.

In general, and so far, the way I approached it, is to use a service (injected into both of the components). When action buttons are clicked, an event is broadcasted from the service and when this event reaches the component 2, its controller sets the corresponding variable (action-1-on, action-2-on, action-3-on, etc) into true and the contents of the ng-include appear.

The problem I'm facing lies exactly in the last step. Let's say for example that inside of one of these templates (e.g action1.html) I have a range element and I want to initialize it as a noUiSlider element. To do that, on the $onInit function of the component2 controller, I add the following code:

var slider = document.getElementById('test-slider');

noUiSlider.create(slider, {
    start: [20],
    step: 1,
    orientation: 'horizontal', 
    range: {
        'min': 0,
        'max': 100
        },
    format: wNumb({
        decimals: 0
        })
    });

What I'm getting back is the error:

TypeError: Cannot read property 'nodeName' of null

and from that, I assume that javascript cannot find the element with the id #test-slider

So, what I want to ask before solving this error, is if this approach (with service and the two components) is reasonable and "angularish" or there is a more straight and clear way to do this (maybe ui-route?). I prefer to work with the more angular way than try to solve this error. If the way I'm approaching is ok, how am I gonna make that element initialized from the $onInit function? Should I add some kind of delay?

Any ideas and opinions are welcome.

I would have gone down the route of each of those Actions being a separate $state. In my opinion setting a trigger for every action you've got is a bit 'unaesthetic'. - LazioTibijczyk
What you are doing with multiple ng-include directives can be done with the <ng-view> directive and a router such as ngRoute or UI-Router. - georgeawg
@georgeawg: Yup I thought it too. But I'm still learning and trying to figure out the best way to do it. In the case, though of the <ng-view> directive, I don't know if the items object could be available inside the route's controller since it belongs to the controller of component2 - J. Doe
There are multiple ways to communicate values between sibling components and there are multiple ways to communicate paramaters to a router view or state. This sounds like an XY-Problem because you don't know how to communicate between external components and views, you try to do it with a sketchy technique. Instead of asking how do to with a straight forward routed SPA, you ask for help with your sketchy technique. - georgeawg