So I've got a solution that allows me to load a route that has waypoints. A couple of notes.
1) I had to add the stops as points and allow the directions widget to make a call to reverse geocode each point.
2) I had to add my actual stops (not waypoints) first then call getDirections() without the waypoints. In my case, routes will have a start and end point with (potentially) waypoints in between to force a route to take certain roads.
3) after getDirections() returns, then add the waypoints as stops.
4) I had to track the index for each waypoint, then coerce the waypoints in my event handler for the directions-start event and set the isWaypoint bool flag to true.
With these caveats, it seemed to work...most of the time. I haven't identified exactly why, but I believe the incremental solving of the route (meaning it solves the route for each stop, then moves on to the next stop), that sometime there existed a race condition between solving the route and updating the stops in the UI for the directions widget. My current workaround, though not great, was to center and zoom to the route's extent prior to loading all the stops. This seems to take just enough time to make it all work. Here's some code (that is still experimental and in development):
loadStops: function (routeData) {
if (routeData != null &&
routeData.Stops != null &&
routeData.Stops.length > 0) {
var stops = JSON.parse(routeData.StopsJson);
if (stops == null) {
return;
}
var numStops = stops.length;
var numWaypoints = 0;
this.map.directions.stopsAsWaypoints = [];
var waypoints = [];
// zoom to avoid race condition? between rest api solve and directions widget
var geo = JSON.parse(routeData.Geometry);
var route = {
geometry: geo,
"symbol": { "color": [0, 0, 0, 255], "width": 5, "type": "esriSLS", "style": "esriSLSSolid" }
};
var routeGraphic = new Graphic(route);
var graphics = [];
graphics[0] = routeGraphic;
var graphicextent = esri.graphicsExtent(graphics);
this.map.setExtent(graphicextent, true);
// Add stops (not waypoints), one at a time.
// Keep waypoints in array to add when directions have finished
for (var index = 0; index < numStops; index++) {
var stop = stops[index];
var point = new Point(stop.feature.geometry);
points[index] = point;
if (stop.feature.attributes.isWaypoint) {
this.map.directions.stopsAsWaypoints[numWaypoints] = index;
waypoints[numWaypoints] = point;//stop;
numWaypoints++;
}
else
{
this.map.directions.addStop(point, index);
}
}
this.map.directions.getDirections().then(lang.hitch(this, function () {
// NOTE: There appears to be a race condition here where directions are recalculated
// if place a breakpoint in directionsstart it works
this.map.directions.addStops(waypoints, this.map.directions.stopsAsWaypoints[0]);
}));
}
}
Here's part of the directions-start event handler:
directionsStartHandler: function (event) {
console.log("Starting directions...");
if (this.embeddedDirections.stops && this.embeddedDirections.stops.length > 2 &&
this.embeddedDirections.stopsAsWaypoints) {
for (var ctr = 0; ctr < this.embeddedDirections.stops.length; ctr++) {
// use jQuery $.inArray to see if this stop is in the waypoint list
if ($.inArray(ctr, this.embeddedDirections.stopsAsWaypoints) != -1) {
this.embeddedDirections.stops[ctr].feature.attributes.isWaypoint = true;
console.log("Waypoint: " + JSON.stringify(this.embeddedDirections.stops[ctr]));
}
}
}