Create Suggester List based on inline data field

What I’m trying to do

My organizational setup has a folder for Entities and People. Each Person note has a field Entity:: [[EntityA]]

Currently I can use dataview to search for people associated with an entity with the following code:

dataview
Table Title, Email, Cell
From "050 People" 
Where contains(string(Entity), "CompanyA")
Where file.link != [[]]

I’ve created a template (thanks to folks on this forum!!) that utilizes JS Execution Commands inside Templater, and want to create a Suggester populated by people associated with a given entity. While this code works for [[CompanyA]] in frontmatter, it doesn’t seem to work when it’s an inline field.

<%*
// Setup key and value to search for
const key = "Entity";
const value = "[[CompanyA]]"
// Loop through all markdown files in vault
const filteredFiles = app.vault.getMarkdownFiles().filter(file => {
  // Get value in frontmatter for specified key above
  const foundValue = app.metadataCache.getFileCache(file)?.frontmatter?.[key];
  // If file doesn't have matching frontmatter key or value is empty, skip
  if (!foundValue) {
    return false;
  }
  // If frontmatter is array of values, check if any of the values match
  if (Array.isArray(foundValue)) {
    return foundValue.includes(value);
  }
  // If frontmatter is not an array, check if value matches exactly
  return foundValue === value;
});
// Prompt user to select file
const selectedFile = (await tp.system.suggester((file) => file.basename, filteredFiles)).basename;
-%>
---
[[<% selectedFile%>]]

I’d love to figure out a way to utilize a CONTAINS function (as I do with dataview code), so it won’t matter whether I have “CompanyA” or “[[CompanyA]]”. Any suggestions are welcome !! Thank you.

Just wanted to bump this one more time to see if there was anyone with any ideas…thx.

I think it would be a whole lot easier to trigger a Dataview query from within the templater script, and then use the output of that to populate your suggester list. The way you script is setup currently, you’re reading through the entire vault searching for potential candidates. If you used a query you would only scan through the metadata, and you’ll get the added benefit of getting all fields (frontmatter or inline).

Here is a mockup which should get you started. You need to change the query according to your setup, and you’ll need to extract and use the relevant information later on in your template.

<%*
const dv = app.plugins.plugins.dataview.api

const result = await dv.query(`
TABLE file.name, title, email, cell
FROM "ForumStuff/f65/f65535"
WHERE entity = "CompanyA"
  AND file.link
`)

if (result.successful ) {
  console.log(result.value.values)
   const selectedPerson = await tp.system.suggester(
     r => r[1], result.value.values)
   tR += JSON.stringify(selectedPerson)

} else
  dv.paragraph(`~~~~\n${ result.error }\n~~~~\n`)
%>

There are two major tricks used in this code. Firstly, we use the Dataview query to populate the result into result.value.values. So test the query, and make sure it returns all the needed information for later processing.

Secondly, when doing the suggester, we present the entire array of resulting values as the second parameter, aka result, and use dereferencing of this result array to pick out what to show in the _first_parameter. Put another way the first parameter says that for each of the values within result.value.values (now called r) , use the second column from the query (aka r[1]) as the value to present in the suggester. When you select something now it’ll return that value of the result.value.values list.

Holroy - that’s amazing. Thank you! Works perfectly.
One quick follow up. I’m hoping to output a link to the person selected from the code, which I can’t seem to do. When I write <% selectedPerson %> below the dashes, I get the Template Parsing Error that selectedPerson is not defined ! I’m sure I’m missing something relatively simple…

1 Like

The templater block as it stands declares the selectedPerson only within the successful handling of the result. You could add let selectedPerson to the top of the block (on the next line after const dv ... ), and change const selectedPerson to selectedPerson within the latter block, and then it should be able to re-use that value later on.

Do however note that if you cancel the suggester, or don’t have a successful run of the query, it’ll be empty and produce no output.

Perfect ! Thanks so very much.

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.