Datacore simple sample code

What I’m trying to do

I am trying to display a table of all files inside my folder. I installed Datacore plugin via BRAT, and now I am trying to get a code that would display my table.

Things I have tried

I am not a programmer, and I am not able to make anything out of documentation on a datacore page. Unfortunately, it is not “normal people” friendly.

I tried to ask GPT, DeepSeek, Mistral and Grok and Grok was the only one that came with some code, but it is not working. I have a folder named Delavnice and note for table named Delavnice DC.

Here is last code from Grok:

const pages = datacore.all()
  .where(page => page.$path.startsWith("Delavnice/") && page.$path !== "Delavnice/Delavnice DC.md")
  .sort(page => page.created || "1970-01-01");
return (
  <table>
    <thead>
      <tr>
        <th>Name</th>
        <th>Created</th>
        <th>Note</th>
        <th>Tags</th>
      </tr>
    </thead>
    <tbody>
      {pages.map(page => (
        <tr>
          <td>{page.$name}</td>
          <td>{page.created || "Not set"}</td>
          <td>{page.updated || ""}</td>
          <td>{page.tags?.join(", ") || ""}</td>
        </tr>
      ))}
    </tbody>
  </table>
);


and this is what I get as preview output:
The datacore script failed to execute.

TypeError: datacore.all is not a function
    at eval (eval at evalInContext (plugin:datacore), <anonymous>:3:564)
    at evalInContext (plugin:datacore:34652:39)
    at asyncEvalInContext (plugin:datacore:34658:28)
    at renderer (plugin:datacore:34832:22)
    at Object.eval [as __] (plugin:datacore:34793:5)
    at B2 (plugin:datacore:13955:15)
    at Array.forEach (<anonymous>)
    at j2 (plugin:datacore:13898:44)


I would be more than grateful for a simple sample of Datacore working code

Give it a try with Dataview. It’s better documented, and you’ll find many great examples on this forum.

You have two options: plain Dataview …

```dataview
TABLE WITHOUT ID file.link AS "Name", file.ctime AS "Created", file.mtime AS "Note", join(tags, ", ") AS "Tags"
FROM "Delavnice" --you need to define this
```

… or “advanced” DataviewJS …

```dataviewjs
dv.table(
    ["Name", "Created", "Note", "Tags"],
    dv.pages('"Delavnice"')  --you need to define this
      .map(p => [
          p.file.link, 
          p.file.ctime, 
          p.file.mtime, 
          p.tags ? p.tags.join(", ") : ""
      ])
);
```

I hope it helps you as a starting point that you can play further.

Cheers, Marko :nerd_face:

Thank you. It displays the table.

I think this is too early stage of plugin for people like me. I believe if I want to have links to files, manual date entry or notes, it would be another rocket science. Maybe it is better to wait until it gets maturity or data view is implemented. Thank you.

1 Like

Here reposting snippet. Last post got flagged by staff. Boring…

function FilesTable() {
  // Directly query pages that are in the "Delavnice" folder
  const content = dc.useQuery(`@page and path("Delavnice")`);

  return (
    <dc.Stack style={{ padding: "20px" }}>
      <table style={{ width: "100%", borderCollapse: "collapse" }}>
        <thead>
          <tr>
            <th style={{ border: "1px solid #ccc", padding: "8px" }}>Name</th>
            <th style={{ border: "1px solid #ccc", padding: "8px" }}>Created</th>
            <th style={{ border: "1px solid #ccc", padding: "8px" }}>Note</th>
            <th style={{ border: "1px solid #ccc", padding: "8px" }}>Tags</th>
          </tr>
        </thead>
        <tbody>
          {content.map(entry => (
            <tr key={entry.$path}>
              <td style={{ border: "1px solid #ccc", padding: "8px" }}>{entry.$name}</td>
              <td style={{ border: "1px solid #ccc", padding: "8px" }}>{new Date(entry.$ctime.ts).toISOString().split("T")[0] || "Not set"}</td>
              <td style={{ border: "1px solid #ccc", padding: "8px" }}>{new Date(entry.$mtime.ts).toISOString().split("T")[0] || "Not set"}</td>
              <td style={{ border: "1px solid #ccc", padding: "8px" }}>{entry.$tags || ""}</td>
            </tr>
          ))}
        </tbody>
      </table>
    </dc.Stack>
  );
}

return FilesTable;

We"ll be around… :saluting_face:
b.

1 Like

Thanks for reposting the snippet without the user insult.

You’ll be around if you abide by the community code of conduct. :saluting_face:

Truly appreciate the feedback, seems the term I used was incorrect and I should of phrased as being laid-back or conventional

You learn everyday :saluting_face:

Okay welp, looks like there was a better approach to creating simple query. You learn everyday.

// A list of columns to show in the table.  
const COLUMNS = [  
{ id: "Name", value: page => page.$link },  
{ id: "Created", value: page => page.value("$ctime") },
{ id: "Modified", value: page => page.value("$mtime") },
{ id: "Tags", value: page => page.value("tags") } 
];  
  
return function View() {  
// Selecting `#game` pages, for example.  
const pages = dc.useQuery(`@page and path("Delavnice")`);  
console.log(pages)
// Uses the built in 'vanilla table' component for showing objects in a table!  
return <dc.VanillaTable columns={COLUMNS} rows={pages} />;  
}

b. :saluting_face:

2 Likes

Slight improvement since it looks like @whdmike wanted to sort entries by date:

// A list of columns to show in the table.  
const COLUMNS = [  
{ id: "Name", value: page => page.$link },  
{ id: "Created", value: page => page.$ctime },
{ id: "Modified", value: page => page.$mtime },
{ id: "Tags", value: page => page.value("tags") } 
];  
  
return function View() {  
// Selecting `#game` pages, for example.  
const pages = dc.useQuery(`@page and path("Delavnice")`);  

// Ensure pages exist and sort them by created date in descending order
const sortedPages = pages?.toSorted((a, b) => b.$ctime - a.$ctime) ?? [];

// Uses the built in 'vanilla table' component for showing objects in a table!  
return <dc.VanillaTable columns={COLUMNS} rows={sortedPages} />;  
}

The big change here is sorting the pages on line 14. I also removed @beto 's console.log to avoid polluting the console and replaced page.value("$ctime") and page.value("$mtime") with page.$ctime and page.$mtime because these values exist in every file, so we can access the preloaded metadata field instead of needing a dynamic call.
:saluting_face:

1 Like

I, being on thin ice related to react and this kind of template code, react to this statement, as it seems like your change could case code breakage if that assumption is not met.

Wouldn’t page.value("$ctime") fail more gracefully, rather than page.$ctime which I’m assuming would give you a compilation error/exception of sorts?

No, I think Datacore’s metadata fails just as gracefully as page.value("$ctime"). From what I can tell, if a note is missing that field, it will display undefined (or NaN if you try to do math on it) in that cell while not affecting the other cells.

If you’re really worried about it, you could use:
{ id: "Created", value: page => page.$ctime ?? "—" },
(creating a fallback of "-" for pages where $ctime doesn’t exist).

If you’re going to do that, you might also want to change the sorting logic:
const sortedPages = pages?.toSorted((a, b) => (b.$ctime ?? 0) - (a.$ctime ?? 0) ) ?? [];
to avoid mistakes in the sorting order.