[Canonical page](<https://docs.dhtmlx.com/planning-engine/wasm/how-to/load-all-task-dates/>)
[Full documentation index](<https://docs.dhtmlx.com/planning-engine/llms.txt>)


# Load all task dates

Get the start, end and duration of every scheduled task from one solve, for example to fill your UI when a project first opens.

By default, `updates` in a [`ScheduleResult`](<https://docs.dhtmlx.com/planning-engine/wasm/api/types/schedule-result.md>) is sparse: it lists only the tasks that moved. Set `includeUnchanged: true` in the [solve options](<https://docs.dhtmlx.com/planning-engine/wasm/api/types/solve-options.md>) and the same solve also reports the tasks that didn't move. You don't need a separate call.

## Steps

1. Serialize the [solve options](<https://docs.dhtmlx.com/planning-engine/wasm/api/types/solve-options.md>) with `includeUnchanged` set to `true`:

   ```js
   const options = JSON.stringify({ includeUnchanged: true });
   ```

2. Pass the options to the call that loads the data. Use [`solve`](<https://docs.dhtmlx.com/planning-engine/wasm/api/project-solve.md>) with a data string for a long-lived [`JsonProject`](<https://docs.dhtmlx.com/planning-engine/wasm/api/json-project.md>), or [`schedule`](<https://docs.dhtmlx.com/planning-engine/wasm/api/schedule.md>) for a one-shot job:

   ```js
   const text = project.solve(JSON.stringify(data), options);
   // or, without a handle: schedule(JSON.stringify(data), options)
   const response = JSON.parse(text);
   ```

3. Check `ok`, then read every entry of [`result.updates`](<https://docs.dhtmlx.com/planning-engine/wasm/api/types/schedule-result.md#updates>). Each entry has `start_date`, `end_date` and `duration` set.

The full example below schedules three tasks. `review` doesn't move, but it's still reported:

```js
const { JsonProject } = require("./pkg-node/plen_wasm.js");

function unwrap(text) {
  const response = JSON.parse(text);
  if (!response.ok) {
    const { kind, code, message, path } = response.error;
    throw new Error(`${kind} ${code ?? ""}: ${message} (at ${path})`);
  }
  return response.result;
}

const data = {
  // 24/7 time keeps the example dates easy to check.
  config: { use_calendars: false },
  tasks: [
    { id: "design", start_date: "2026-01-01 00:00", duration: 2 },
    { id: "build", start_date: "2026-01-01 00:00", duration: 1 },
    { id: "review", start_date: "2026-01-05 00:00", duration: 1 },
  ],
  links: [{ id: "design-build", source: "design", target: "build", type: "fs" }],
};

const options = JSON.stringify({ includeUnchanged: true });

const project = new JsonProject("{}");
try {
  const result = unwrap(project.solve(JSON.stringify(data), options));
  for (const u of result.updates) {
    console.log(`${u.id} ${u.start_date}..${u.end_date} ${u.duration}`);
  }
} finally {
  project.free();
}
```

Each entry of `updates` looks like this:

```json
{ "duration": 2, "end_date": "2026-01-03 00:00", "id": "design", "kind": "task", "start_date": "2026-01-01 00:00" }
```

## Get the full list from an already solved project

To reload every date later, call [`solve`](<https://docs.dhtmlx.com/planning-engine/wasm/api/project-solve.md>) without data and with the same options. On a solved project with no pending edits, the call doesn't replan or change the accepted state, and [`baselineId`](<https://docs.dhtmlx.com/planning-engine/wasm/scheduling/reading-results.md#baseline-token>) stays the same:

```js
const allDates = unwrap(project.solve(undefined, options));
```

Switch back to sparse results for the edits that follow. `"{}"` returns only what changed:

```js
const next = unwrap(project.solve(undefined, "{}"));
```

The result cache uses the whole options object as its key. An `includeUnchanged` call never gets a cached sparse result, and a sparse call never gets a cached full one.

## What is and isn't reported

- The result includes every scheduled task: leaf tasks, summaries and milestones. Check each entry's `kind` (`"task"`, `"summary"` or `"milestone"`) to tell them apart.
- Tasks with [`unscheduled: true`](<https://docs.dhtmlx.com/planning-engine/wasm/api/types/task-data.md>) are never reported.
- `leveling_delay` and `pauses` never appear, because a solve doesn't change them.
- `baselineId` follows real changes only. Asking for unchanged tasks doesn't create a new baseline.
- With [`subtree`](<https://docs.dhtmlx.com/planning-engine/wasm/how-to/reschedule-a-branch.md>), the result holds every task in the subtree, including the subtree tasks' ancestors. Tasks outside the subtree appear only when a sparse subtree solve would report them too, because they changed or were edited.
- On a project with a dependency cycle, nothing is scheduled. The result still lists every scheduled task, in model order, with its dates and duration as stored. `subtree` is ignored, and no entry has a `reason`, even with [`reasons: true`](<https://docs.dhtmlx.com/planning-engine/wasm/api/types/solve-options.md>).
- [`preview`](<https://docs.dhtmlx.com/planning-engine/wasm/api/project-preview.md>) and [`level`](<https://docs.dhtmlx.com/planning-engine/wasm/api/project-level.md>) always return sparse updates. [`PreviewOptions`](<https://docs.dhtmlx.com/planning-engine/wasm/api/project-preview.md#previewoptions>) has no `includeUnchanged` field.

## Result

Run the example with `node`. It prints one line per task, including `review`, which didn't move:

```text
design 2026-01-01 00:00..2026-01-03 00:00 2
build 2026-01-03 00:00..2026-01-04 00:00 1
review 2026-01-05 00:00..2026-01-06 00:00 1
```

Without `includeUnchanged`, the same solve reports only `build`.

See [Reading results](<https://docs.dhtmlx.com/planning-engine/wasm/scheduling/reading-results.md>) for how to write the dates back into your model.
