Convert a Dataview code into a number

Hi, I’m new to Obsidian and I’ve never learned to program. So far I’ve been inspired by bits of code I found on the Obsidian Super Community forum. If I am asking your help today, it is because I have not found a solution to my problem and I would be delighted if one of you could help me.

What I’d like to do:

1. Count the number of tasks done each day as well as the number of tasks created, and display the numbers on the daily note via Dataview plugin.

exemple in the daily note : #NOTD:2 #NOTC:3

2. Monitor the evolution of its numbers in a chart on the weekly note with Tracker plugin.

exemple in the weekly note : (chart of the tasks created and done each day of the week)

The problem:
Here are the formulas I use to count the number of tasks created and done each day. This formula displays the right number but the Tracker plugin I use for the chart does not recognize the formula as a number. (note: my tasks are individual notes with the task in it)

#NOTD:

$=dv.pages('"All/Zones/Objectifs"').where(p => p.file.mday.day == dv.current().file.day.day).sort(p => p.file.name, 'desc').file.tasks.where(t => t.completed).length

#NOCT:

$=dv.pages('"All/Zones/Objectifs"').where(p => p.file.cday.day == dv.current().file.day.day).sort(p => p.file.name, 'desc').file.tasks.length

Graph :

searchType: tag
searchTarget: NTEA, NTCA
datasetName: NOTD, NOCT
folder: All/dailynotes
startDate: -1W
endDate: +1W
line:
    title: Tâches effectué & Tâches créée
    yAxisLabel: Nombre de Tâches
    yMin: 0, 0
    lineColor: yellow, red
    showLegend: true
    legendPosition: right

So my question is, is there a way to convert the value given by dataview into a «real» number readable by the plugin tracker ?

1 Like

I had a very similar issue. My solution was to use the API of the community plugin MetaEdit to set the fields in my daily note rather than having dataview do it directly. So the fields themselves were just numbers and elsewhere on the page I had a dataviewjs code block which used MetaEdit’s update function to update them with the values.

Hi @scholarInTraining, thank you for your answer! I have never used meta edit yet but your solution is interesting. Would you have some of the code you used to update the fields please?

1 Like

I found this but I’m having trouble adapting it to my case, I’m not sure it’s right for me : MetaEdit plugin - #28 by Christian

1 Like

First, here is how I call my code inside a dataviewjs block on my daily note, passing it the info about the page:

await dv.view("path/To/updateTodayFields", dv.current());

Then here is the part of updateTodayFields.js where I first count finished tasks on the page that I passed as input. Then I use metaedit to update a DV inline field on that page that currently reads Tasks Done Today:: 0. I have my dataview settings for automatic view refreshing at an interval of every 30 seconds, so if I check off a task on my daily notes page I should see the count increase on that day within 30 seconds. (The default refreshing rate is much faster, but that was causing annoying screen flickering for me, so I reduced it.)

async function updateTodayFields(input, dv) {
    if (!input) return;
    const { update } = this.app.plugins.plugins.metaedit.api;

    const howMany = input.file.tasks.where(t => t.completed).length;
    await update('Tasks Done Today', howMany, input.file.path);
}

You’ll probably want to change the calculation of howMany to match your very nice queries above. Just note that if you change what you pass in as the second argument to dv.view then the value of input will change in the script file and that is used both for calculation and in the last line of code to figure out which page’s field to update!
Good luck!

1 Like

Thank you very much for this information, I tried to follow your advice but I still have some small problems. I try to create two variables in the dataviewjs block and then send them to the updateTodayFields function that would update them but it doesn’t work. I’m sorry to bother you with this.

dataviewjs block :


let notd = dv.pages('"All/Zones/Objectifs"').where(p => p.file.mday.day == dv.current().file.day.day).sort(p => p.file.name, 'desc').file.tasks.where(t => t.completed).length;

let noct = dv.pages('"All/Zones/Objectifs"').where(p => p.file.cday.day == dv.current().file.day.day).sort(p => p.file.name, 'desc').file.tasks.length ;

await dv.view("All/Templates/functions/updateTodayFields", notd , noct);

js function :

async function updateTodayFields(input, dv) {
if (!input) return;
const { update } = this.app.plugins.plugins.metaedit.api;

const howManyTD = input.notd;
const howManyCT = input.noct;

await update('Tasks Done Today', howManyTD, input.file.path);

await update(‘Tasks Created Today’, howManyCT, input.file.path);
}

Very nice! You just want to change slightly the format of your call to dv.view. When sending it multiple arguments, it wants them inside an object. Also, is the file with the fields that you want to update dv.current() in your dataviewjs block? If not, you’ll want to change.

New last line of the dataviewjs block:

await dv.view("All/Templates/functions/updateTodayFields", 
{ "notd": notd, "noct": noct, "updatePath": dv.current().file.path }
);

(line breaks all optional and just to make it easier to read on the forum).

New last two lines of your js function just have a change at the end of the lines:

await update('Tasks Done Today', howManyTD, input.updatePath);
await update('Tasks Created Today', howManyCT, input.updatePath);

Does this make sense? The dataview documentation is really sparse here! Also, if anything doesn’t work, you can add lines to console.log(...) your different variables in either portion of your code to make sure everything is what you expect.

Yes, thanks @scholarInTraining it makes sense. I’ve put your advice into practice but it still doesn’t work. I looked in the console with (CTRL + SHIFT + I ) but I don’t see any error message. How can I use consol.log() to find the cause of the problem?

1 Like

No error messages is definitely a good thing! The first thing I would do would be in your dataviewjs code, before you even call out to your script with dv.view, console.log("dataviewjs noct: " + noct); and the same for notd. This’ll double-check that your numbers are being calculated correctly. Then inside the JS script I’d put in some similar log statements checking the stuff inside input, including the path. Hopefully, that’ll give you more information about what is happening!

Ok thank you !
So the number are right in the dataviewjs block but when I put this code in the js file :

async function updateTodayFields(input, dv) {
    if (!input) return;
    const { update } = this.app.plugins.plugins.metaedit.api;

    const howManyTD = input.notd;
    const howManyCT = input.noct;

console.log("JS: " + howManyTD);

await update('Tasks Done Today', howManyTD, input.updatePath);
await update('Tasks Created Today', howManyCT, input.updatePath);
}

I see this message in the console :

[Violation] 'requestAnimationFrame' handler took 75ms

1 Like

Hi @scholarInTraining, I tried to combine the java script file with the dataview block and it works! Is there a particular reason why the js file is preferred over the two code conbination ?

```dataviewjs

let notd = dv.pages('"All/Zones/Objectifs"').where(p => p.file.mday.day == dv.current().file.day.day).sort(p => p.file.name, 'desc').file.tasks.where(t => t.completed).length;

let noct = dv.pages('"All/Zones/Objectifs"').where(p => p.file.cday.day == dv.current().file.day.day).sort(p => p.file.name, 'desc').file.tasks.length ;

const filePath = dv.current().file.path;
const {update} = app.plugins.plugins["metaedit"].api;

console.log("dataviewjs notd: " + notd);
console.log("dataviewjs noct: " + noct);

await update('Tasks Done Today', notd, filePath);
await update('Tasks Created Today', noct, filePath);

Well I have no idea why you were getting those results but I am glad you got something working! I have it in a separate file in case I decide later that I want to do any additional calculation then I won’t have to go update the code in every daily note. Not so relevant for counting tasks done but one of the other fields I am updating I am less sure of my code for counting it. I think you are quite right that you can just go with a dataviewjs block in your case. Sorry for not suggesting that: I mixed your question up with another at first when I was sharing my code.

1 Like

Hi @scholarInTraining ! No problem, thank you so much for your support!