blacksmithgu / obsidian-dataview

A data index and query language over Markdown files, for https://obsidian.md/.
https://blacksmithgu.github.io/obsidian-dataview/
MIT License
6.89k stars 406 forks source link

Is dv.view() function not a async function? #945

Closed LumosLovegood closed 2 years ago

LumosLovegood commented 2 years ago

What happened?

Evaluation Error: SyntaxError: await is only valid in async function at new Function () at DataviewInlineApi.view (eval at (app://obsidian.md/app.js:1:1433712), :15617:24) at async DataviewJSRenderer.render (eval at (app://obsidian.md/app.js:1:1433712), :16267:13)

DQL

dv.view("Template/weatherForecast")

JS

const key = "74f8f1c033244ebda3a957464c572a29";
const today = window.moment().format("gggg-MM-DD");

if(dv.current().date.ts==dv.date(today).ts){
    let location = await searchCity("tianxin");
    let weather = await getWeather(location);
    dv.table(["Date","Weather","Temperature","MoonPhase","Cloud"],weather.map(t => [t.fxDate.substring(5),t.textDay,t.tempMin+"~"+t.tempMax+"℃",t.moonPhase,t.cloud]));
}
async function getWeather(locationId){
    let weatherUrl = `https://devapi.qweather.com/v7/weather/7d?                    location=${locationId}&key=${key}`;
    let wUrl = new URL(weatherUrl);
    const res = await request({
        url: wUrl.href,
        method: "GET",
    });
    let data = JSON.parse(res);
    if(data.code=="200"){
        return data.daily;
    }
    return -1;
}

async function searchCity(city){
    let searchUrl = `https://geoapi.qweather.com/v2/city/lookup?location=${city}&key=${key}&number=1`;
    let sUrl = new URL(searchUrl);
    const res = await request({
        url: sUrl.href,
        method: "GET",
    });
    let data = JSON.parse(res);
    if(data.code=="200"){
    return data.location[0].id;
 }
    return -1;
}

Dataview Version

0.4.26

Obsidian Version

0.13.33

OS

Windows

blacksmithgu commented 2 years ago

This is supported on develop but not the latest release; 0.5.0 should fix this for your use case.

LumosLovegood commented 2 years ago

Thanks! And I found a solution for this use case.
Putting the view creator function in an async function can solve this problem.

In my javascript:

weatherView();
async function weatherView(){
    let weather = await getWeather(city,days);  
    dv.table(["date","weather","temp","cloud","moonPhase"],weather.map(t => [t.fxDate.substring(5),t.textDay,t.tempMin+"~"+t.tempMax+"℃",t.cloud+"%",t.moonPhase]));
}

In dataviewjs:

dv.view("Utils/Scripts/weatherView",setting)