MrYutz
MrYutz

Reputation: 438

How do you implement save() and load() for TradingView's Charting Library

While trying to implement TradingView's Save and Load Low-Level API, I could not get the library to refresh the screen while loading the Object returned from the backend.

load() would just cause the screen to flash, with no errors. The chart would not update.

How do you save and load data from the TradingView widget in an Angular Frontend?

Upvotes: 4

Views: 4648

Answers (1)

MrYutz
MrYutz

Reputation: 438

I can confirm that save() and load() are working without issue on my project. It took a bit of fussing with Types to get it working. I am sure someone will look at this pile and despair - but it works.

So for anyone else that wants to test:

tvWidget.load(savedObject)
tvWidget.save((saveObject) => this.chartService.saveCurrentChart(saveObject))

I created a save button in the tvWidget header:

    const saveButton = tvWidget.createButton();
    saveButton.setAttribute('title', 'Click to Save Chart');
    saveButton.classList.add('apply-common-tooltip');
    saveButton.addEventListener('click', () => tvWidget.save((saveObject) => this.chartService.saveCurrentChart(saveObject, tvWidget)))
    saveButton.innerHTML = 'Save Chart';

And a Load Button in the tvWidget header:

    createDrawingButton(tvWidget: IChartingLibraryWidget) {
    const loadButton = tvWidget.createButton();
    loadButton.setAttribute('title', 'Click to Load Chart');
    loadButton.classList.add('apply-common-tooltip');
    loadButton.addEventListener('click', () => tvWidget.load(this.chartService.loadSavedChart()));
    loadButton.innerHTML = 'Load from Backend';

Here is my TypeScript Interface:

export interface APIChartData {
    ltChartId?: number | undefined
        tvChartId?: string | undefined
    chartObject: Object
        lastUpdate?: number | undefined
}

Here is my Save Function:

saveCurrentChart(tvChartObject: any) {

let chartID = tvChartObject['charts'][0]['panes'][0]['sources'][0]['id'];
let chartToSave: APIChartData = {
      ltChartId: this._currentChart?.ltChartId,
      tvChartId: chartID,
      chartObject: tvChartObject,
      lastUpdate: Math.floor(Date.now() / 1000),
    };

    this.postChart(chartToSave).subscribe((response) => {

      console.log("Response from Server")
      console.log(response.ltChartId)
      this._savedChartId =  response.ltChartId
    });

    console.log(`Saved Chart Object`);
  }

private postChart(saveChart: APIChartData): Observable<ChartStoreResponse> {
    console.log('Trying to save...');
    const httpOptions = {
      headers: new HttpHeaders({
        'Content-Type': 'application/json',
        accept: 'application/json',
        Authorization: this._oAuthTokent,
      }),
    };

Here is my Load Function:

loadSavedChart(chartID:number = this._savedChartId): Object {

    console.log('Trying to load...');
    const httpOptions = {
      headers: new HttpHeaders({
        'Content-Type': 'application/json',
        accept: 'application/json',
        Authorization: this._oAuthTokent,
      }),

      params: new HttpParams().set('chart', chartID.toString()),
    };

    const httpParams = {};

    // My "Backend" in a docker image locally running FASTAPI
    const LoadURL = 'http://localhost/api/v1/tradingview';

    let chartObject: Object = {};

    let loadChart$ = this.http
      .get<APIChartData>(LoadURL, httpOptions)
      .pipe(tap(() => console.log('Loaded the goods.')));

    loadChart$.subscribe((object) => {

      this._chartFromDisk = object.chartObject;
      console.log(`Chart ${chartID} from Server Store:`)
      console.log(object.chartObject);

    });

    return this._chartFromDisk;
  }

Upvotes: 7

Related Questions