0

Has any one figure out on how to load the server data from the ng2-smart table plugin of Angular2.

I have few products data that is retrieved from Node API and Im able to display the same onClick event in the browser log.

I need to display the same in this 3rd party plugins table area which they have provided in this documentation below:

Frontend : https://akveo.github.io/ng2-smart-table/#/examples/populate-from-server

Under "Server Data Source Example"

Code: https://github.com/akveo/ng2-smart-table/blob/master/src/app/pages/examples/server/advanced-example-server.component.ts

Accordingly i have configured in my code as below:

blank-page.component.ts

import { ServerDataSource } from 'ng2-smart-table'; 
import { Component } from '@angular/core';
import { Http } from '@angular/http';

@Component({
  selector: 'advanced-example-server',
  template: `
     <ng2-smart-table [settings]="settings" [source]="source"></ng2-smart-table>
 `,
   })

export class BlankPageComponent implements OnInit {
    settings = {
    columns: {
      id: {
        title: 'ID',
      },
      albumId: {
        title: 'Album',
      },
      title: {
        title: 'Title',
      },
      url: {
        title: 'Url',
      },
    },
  };

    source: ServerDataSource;

   //Doubt or Problem here!!!  
   constructor(http: Http) {
    this.source = new ServerDataSource(http, { endPoint: 'https://jsonplaceholder.typicode.com/photos' });
  }

  //Tried like this too (Which is not the right way of calling)
  constructor(http: Http) {
    this.source = new ServerDataSource(http, { endPoint: this.productService.getProductsOncategory(this.categoryid)  });
  }

 //Dint work this too!!

 constructor(http: Http) {
    this.source = new ServerDataSource(http, { endPoint:'http://localhost:5000/products/getProductsOncategory ' });
  }
}

Where my service.ts file is like, which actually displays the products data in my browser log which i need to show in my table data

getProductsOncategory(category_id){

  let catUrl="http://localhost:5000/products/getProductsOncategory"
  let headers = new Headers();
  headers.append('Content-Type','application/json');
  let catIdObj = JSON.stringify({category_id:category_id})
  console.log(catIdObj)
  return this.http.post(catUrl,catIdObj,{headers:headers})
  .map((response:Response)=>response.json())
  .do(data=>console.log(JSON.stringify(data)))
  .catch(this.handleError);
}

Error if i use my projects url in endpoint

Error: Uncaught (in promise): Error: Data must be an array. Please check that data extracted from the server response by the key '' exists and is array.

phyme
  • 331
  • 2
  • 11
  • 25

4 Answers4

3

This is what i did and worked perfect for me, i used smart table server side paging, but build my own filter for custom filtration experience.

1- Define Server Data Source source: ServerDataSource;

2- set it in constructor with config object

this.source = new ServerDataSource(http,
  {
 endPoint: 'full-url-for-endpoint', 
 dataKey: 'your-list-path-from-response' for example 'data.records' , 
 pagerPageKey: 'your backend param excpected for page number key', 
 pagerLimitKey: 'your backend param excpected for page size',
 totalKey: total records returned in response path for example 'data.total',
 filterFieldKey: your filter keys template should set to '#field#' if you need to send params as you set, Default is '#field#_like'
  });`

3- add settings object

settings = {
actions: {
  custom: [ // if you need custom actions do like that 
    { name: 'view-something', title: '<i title="Exception" class="nb-alert"></i>' },
    { name: 'do-custom', title: '<i class="fa  fa-pencil"></i>' }
  ],
  add: true, //if you don't need default add button set to false 
  edit: true, //if you don't need default add button set to false 
  delete: true, //if you don't need default delete button set to false 
  position: 'right' // buttons position 
}, // remove add , edit , delete objects if you don't use 
    add: {
  addButtonContent: '<i class="nb-plus"></i>',
  createButtonContent: '<i class="nb-checkmark"></i>',
  cancelButtonContent: '<i class="nb-close"></i>',
},
edit: {
  editButtonContent: '<i class="nb-edit"></i>',
  saveButtonContent: '<i class="nb-checkmark"></i>',
  cancelButtonContent: '<i class="nb-close"></i>',
},
delete: {
  deleteButtonContent: '<i class="nb-trash"></i>',
  confirmDelete: true,
},
pager: {
  display: true // set to false if no need for pagination 
},
columns: { 
  Id: {  // set up table cols - Id is a prop name returned from backend
    title: 'ID',  // display name in table header 
    type: 'number',
    filter: false  // add text filter for it or not 
  },
  Name: {
    title: 'Full Name',
    type: 'string',
    filter: false
  }
}
};

// Add Filter Data , i used a custom form binded with ngModel above table for filtration, so assume you have a model called filter which get data from external form

 FilterData() {

this.source.reset(true);  // reset your old filtered data 
this.source.setPage(1, false); // set page to 1 to start from beginning 

let filterArr = this.getFilterArray(); // add a new filter data, but be careful to not sent any empty data, as it throws an exception 
if (filterArr.length)
  this.source.setFilter(filterArr, false, false);

this.source.refresh(); // this will call the server with new filter and paginatio data
}

getFilterArray() {  // setup new filter 
let filterArray = [];
if (this.filter.id)
  filterArray.push({ field: 'id', search: this.filter.id });
if (this.filter.name)
  filterArray.push({ field: 'name', search: this.filter.name});

return filterArray;  
}
 onCustomAction(event) {  // custom buttons code 
  switch (event.action) {
    case 'view-something':
     // put your code here 
     break;
    default:
     console.log('Not Implemented Action');
    break;
}
}
Mohamed Magdi
  • 276
  • 2
  • 5
2

With this example my data is resource so the datakey is set resource

find below sample code

{

source: ServerDataSource;

constructor(http: HttpClient) {

this.source = new ServerDataSource(http, { dataKey: 'resource', endPoint:'http://localhost:8080/api/v2/mysql/_table/able' })

}
Roman Pokrovskij
  • 9,449
  • 21
  • 87
  • 142
eboakyegyau
  • 225
  • 1
  • 13
0

You need to set the dataKey for the ServerDataSource. For example, if your JSON is { data: [...], total: .. }, you need to set dataKey = 'data'.

tuomastik
  • 4,559
  • 5
  • 36
  • 48
Danche
  • 1
  • 2
0

this worked for me on Angular 8, But Search box functionality needs to be handeled from backend (i.e: localhost:5000/session_info/Seance1?temp_like=30), so backend need to filter (temp_like = value) in database, which make search box retrive live data. Here is the entire component with Edit and Delete, Enjoy it!

import {Component} from '@angular/core';
import {ServerDataSource} from 'ng2-smart-table';
import {HttpClient} from "@angular/common/http";
import {Setting} from "../../setting";

@Component({
  selector: 'ngx-session-man',
  templateUrl: './sessions-man.component.html',
  styleUrls: ['./sessions-man.component.scss'],
})
export class SessionsManComponent {

  settings = {
    mode: 'inline',
    add: {
      addButtonContent: '<i class="nb-plus"></i>',
      createButtonContent: '<i class="nb-checkmark"></i>',
      cancelButtonContent: '<i class="nb-close"></i>',
    },
    edit: {
      editButtonContent: '<i class="nb-edit"></i>',
      saveButtonContent: '<i class="nb-checkmark"></i>',
      cancelButtonContent: '<i class="nb-close"></i>',
      confirmSave: true,
    },
    delete: {
      deleteButtonContent: '<i class="nb-trash"></i>',
      confirmDelete: true,
    },
    columns: {
      name: {
        title: 'Séance',
        type: 'string',
      },
      start: {
        title: 'Début',
        type: 'any',
      },
      end: {
        title: 'Fin',
        type: 'any',
      },
    },
  };
  source: ServerDataSource;

  constructor(private httpClient: HttpClient) {
    this.source = new ServerDataSource(this.httpClient, {endPoint: Setting.baseUrl + 'all_sessions_table'});
  }

  onDeleteConfirm(event): void {
    if (window.confirm('Are you sure you want to delete ' + event['data']['name'] + '?')) {
      event.confirm.resolve();
      this.httpClient.delete<any>('http://localhost:5000/del-seance/' + event['data']['name']).subscribe(
        temps => {});
    } else {
      event.confirm.reject();
    }
  }

  onEditConfirm(event): void {
    if (window.confirm('Are you sure you want to edit ' + event['data']['name'] + '\'s name to ' + event['newData']['name'] + '?')) {
      event.confirm.resolve();
      this.httpClient.post<any>('http://localhost:5000/mod-seance/' + event['data']['name'] + '/' + event['newData']['name'], { title: 'Session deleted' }).subscribe(
        temps => {});
    } else {
      event.confirm.reject();
    }
  }
}