can´t list key in array - react-hooks

Dear knowledgeable SO members!
I´m trying to list player.id, player.number and player.totPoints
I have this code:
const [number, setNumber] = useState('')
const [totPoints, setTotPoints] = useState(0)
const [players, setPlayers] = useState([]);
const addHandler = () => {
const newTotPoints = setTotPoints(prevState => prevState + 1)
setPlayers([...players, {
id: players.length,
number: number,
totPoints: newTotPoints
}])
}
<table class="table">
<thead>
<th>id</th>
<th>Number</th>
<th>Points scored</th>
</thead>
<tbody>
{
players.map(player => (
<tr>
<td>{player.id}</td>
<td>{player.number}</td>
<td>{player.totPoints}</td>
</tr> ))
}
</tbody>
</table>
and can´t list player.totPoints as you can see
Hope you can help mee

Related

data not displaying in table in vuejs

i have created vue file to display data in frontend. but i'm unable to print 2 tables on same page at same time. only table 2 is displaying data , in first table it shows data for 2 seconds and than disappears. what i'm doing wrong? please help. i am super new in vuejs and have not much knowledge.
here is my index.vue file,
Table 1
<tbody>
<tr
v-show="items && items.length"
v-for="(data, i) in items"
:key="i">
<td></td>
<td></td>
</tr>
and this is function code,
async fetchData1() {
this.$store.state.operations.loading = true;
let currentPage = this.pagination ? this.pagination.current_page : 1;
await this.$store.dispatch("operations/fetchData", {
path: "/api/calldata?page=",
currentPage: currentPage + "&perPage=" + this.perPage,
});
table 2
<tbody>
<tr
v-show="items && items.length"
v-for="(data, i) in items"
:key="i">
<td></td>
<td></td>
</tr>
and here is the function for table 2
async fetchData2() {
this.Loading2 = true
let currentPage = this.Pagination2 ? this.Pagination2.current_page : 1;
await this.$store.dispatch("operations/fetchData", {
path: "/api/datacall/data2?page=",
currentPage: currentPage + "&perPage=" + this.perPage,
});
this.Loading2 = false;
and this are the controller functions
public function index(Request $request)
{
return DataResource::collection(Datamodl::with('user')->where('type',1)->latest()->paginate($request->perPage));
}
public function index2(Request $request)
{
return DataResource::collection(Datamodl::with('user')->where('type',0)->latest()->paginate($request->perPage));
}
And Route ,
Route::get('/calldata/data2', [DataController::class, 'index2']);
Route::apiResource('calldata', DataController::class);
Observation : You are updating same variable which is items for both the tables. Hence, it is overriding the latest items with the old items array.
Solution : Here is the implementation as per my comment.
new Vue({
el: '#app',
data: {
table1Items: null,
table2Items: null
},
mounted() {
this.fetchData1();
this.fetchData2();
},
methods: {
fetchData1() {
this.table1Items = [{
id: 1,
name: 'table 1 alpha'
}, {
id: 2,
name: 'table 1 beta'
}]
},
fetchData2() {
this.table2Items = [{
id: 1,
name: 'table 2 alpha'
}, {
id: 2,
name: 'table 2 beta'
}]
}
}
})
table, th, td {
border: 1px solid black;
margin: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<table>
<thead>
<th>ID</th>
<th>Name</th>
</thead>
<tbody>
<tr v-show="table1Items" v-for="(data, i) in table1Items" :key="i">
<td>{{ data.id }}</td>
<td>{{ data.name }}</td>
</tr>
</tbody>
</table>
<table>
<thead>
<th>ID</th>
<th>Name</th>
</thead>
<tbody>
<tr v-show="table2Items" v-for="(data, i) in table2Items" :key="i">
<td>{{ data.id }}</td>
<td>{{ data.name }}</td>
</tr>
</tbody>
</table>
</div>
you are using same property which is items for both. so second request will changed first items. so in both table same data will visible. you have to store in different state property for different data rendering.
solution :
make another action fetchData2.
call another mutation setItems2. add state propery item2: []. and setItems2 value from this mutation.
render second table like this.
<tr
v-show="items2.length"
v-for="(data, i) in items2"
:key="i">
<td></td>
<td></td>
</tr>
For code quailty:
give proper and related variable name . don't use items1 and items2 like that.
never used v-if/v-show and v-for in same element.for more info
use template first in this senerio.
use the item's unique id instead of the index in the key.
if you take the items default value as [], instead of null, then you only required to check items.length instead of items && items.length. so always use list default value []
if both requests are not dependent on each other then you should use Promise.all() for fetching data concurrently. which saved tremendous time and also in this case you don't require two loading property.

laravel vue send array to backend

I want to send array of id's to backend with one button from vuejs table but i get error 500.
Logic
Check the check boxes
Collect the id's
Send id's to back-end when click on button
update the view
Code
template
<table class="table table-dark table-hover table-bordered table-striped">
<thead>
<tr>
<th class="text-center" width="50">
//the button
<button class="btn btn-outline-danger" #click="withdraw(index)">Withdraw</button>
</th>
<th class="text-center" width="50">#</th>
<th class="text-center">Amount</th>
</tr>
</thead>
<tbody>
<tr v-for="(income,index) in incomes" v-bind:key="index">
<td class="text-center">
//check box input
<input v-if="income.withdraw == '0'" type="checkbox" :id="income.id" :value="income.amount" v-model="checkedNumbers">
</td>
<td class="text-center">{{index+1}}</td>
<td class="text-center">Rp. {{formatPrice(income.amount)}}</td>
</tr>
<tr>
<td colspan="2"></td>
<td>
<span>Withdraw for today, Sum: <br> Rp. {{ formatPrice(sum) }}</span>
</td>
</tr>
</tbody>
</table>
script
export default {
data() {
return {
incomes: [],
checkedNumbers: [],
}
},
computed: {
sum() {
return this.checkedNumbers.reduce(function (a, b) {
return parseInt(a) + parseInt(b);
}, 0);
}
},
methods: {
withdraw(index) {
let checkedids = this.incomes[index]
axios.post(`/api/withdrawbutton/`+checkedids).then(response => {
this.income[index].withdraw = '1'
this.$forceUpdate()
});
}
}
}
route
Route::post('withdrawbutton/{id}', 'IncomeController#withdrawbutton');
controller
public function withdrawbutton($id)
{
$dowithdraw = Income::where('id', $id)->get();
$dowithdraw->withdraw = '1';
$dowithdraw->save();
return response()->json($dowithdraw,200);
}
Any idea where is my mistake and how to fix it?
......................................................................................................................
Don't send the list as a GET parameter, send it as a POST:
let params = {}
params.ids = this.checkedNumbers
axios.post(`/api/withdrawbutton/`, params)
.then(response => {
this.income[index].withdraw = '1'
this.$forceUpdate()
});
Controller
public function withdrawbutton(Request $request)
{
$dowithdraws = Income::whereIn('id', $request->input('ids', []));
$dowithdraws->update(['withdraw' => '1']);
return response()->json($dowithdraws->get(), 200);
}
Route
Route::post('withdrawbutton/', 'IncomeController#withdrawbutton');
And I don't think you need to update anything in the front because you already have them checked (if you want to keep them checked)

Testing Angular 2 Component ngOnInit with Karma/Jasmine

I am trying to test my Angular 2 Template but doing something incorrect as I don't get any filteredFirms to repeat through.
Here is my directive controller code:
(my actual firm service is just getting a dummy json file and return an array of firm objects, but I'm not testing my service here so I'm mocking this call as you can see in my spec file below.)
export class FirmListComponent implements OnInit {
constructor(public firmService: FirmService) { }
public ngOnInit() {
this.firmService.stateObservable.subscribe((state) => {
this.firms = state.firms;
this.filteredFirms = this.firms;
});
this.getFirms();
}
public getFirms(value?: string) {
this.loading = true;
this.firmService.getFirms(value).subscribe((response: any) => {
this.loading = false;
});
}
}
}
My directive template:
<thead>
<tr>
<th class="checkbox-col">
<md-checkbox [(ngModel)]="selectAll" (click)="selectAllChanged()" aria-label="Select All"></md-checkbox>
</th>
<th>
Firm Name
</th>
<th>
Country
</th>
<th>
Industry
</th>
<th>
EDF
</th>
<th>
LGD
</th>
<th>
Modified
</th>
<th>
Modified By
</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let firm of filteredFirms; let i = index" class="animate-repeat" [ngClass]="{'active': firm.selected}">
<td class="checkbox-col">
<md-checkbox [(ngModel)]="firm.selected" aria-label="firm.name" (change)="selectFirm(i)"></md-checkbox>
</td>
<td>{{firm.name}}</td>
<td>{{firm.country}}</td>
<td>{{firm.industry}}</td>
<td>
<span class="label bg-purple600">US 4.0</span>
<span class="label bg-green600">US 4.0</span>
</td>
<td>
<span class="label bg-pink800">US 4.0</span>
<span class="label bg-orange300">US 4.0</span>
</td>
<td>{{firm.modifiedOn}}</td>
<td>{{firm.modifiedBy}}</td>
</tr>
</tbody>
My tests for the table head portion pass just fine, but I don't get any rows when I try to test the table body.
My spec file testing the template:
describe('Firm List Component', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [MaterialModule, FormsModule, AppModule],
declarations: [FirmListComponent],
providers: [FirmService]
})
.compileComponents()
.then(() => {
fixture = TestBed.createComponent(FirmListComponent);
component = fixture.componentInstance;
debugEl = fixture.debugElement;
element = fixture.nativeElement;
firmService = fixture.debugElement.injector.get(FirmService);
// mockFirms is just an array of objects with firm data
getObservableSpy = spyOn(firmService, 'stateObservable')
.and.returnValue(mockFirms);
getFirmsSpy = spyOn(firmService, 'getFirms')
.and.returnValue(Observable.of(mockFirms));
});
}));
it('should show firms after getFirms observable', () => {
fixture.detectChanges();
fixture.whenStable().then(() => {
fixture.detectChanges();
// this test passes
var rowHeaderLength = element.querySelectorAll('th').length;
expect(rowHeaderLength).toBe(8);
// this test does not, rowDataLength is 0
// selecting the rows by class so I don't get the tr in the header here
var rowDataLength = element.querySelectorAll('.animate-repeat').length;
expect(rowDataLength).toBe(10);
});
});
}
Any help is appreciated. Thanks

CI PHPExcel, How to import one multi-sheet xlsx to multiple table in sql database?

As I state in the title,
Is it possible to do such thing?
May I have the example?
Thanks in advance
this is jquery it will be easy to do
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<body>
<table id="tbl1" class="table2excel">
<tr>
<td>Product</td>
<td>Price</td>
<td>Available</td>
<td>Count</td>
</tr>
<tr>
<td>Bred</td>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
<tr>
<td>Butter</td>
<td>4 </td>
<td>5 </td>
<td>6 </td>
</tr>
</table>
<hr>
<table id="tbl2" class="table2excel">
<tr>
<td>Product</td>
<td>Price</td>
<td>Available</td>
<td>Count</td>
</tr>
<tr>
<td>Bred</td>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
<tr>
<td>Butter</td>
<td>14</td>
<td>15</td>
<td >16</td>
</tr>
</table>
<hr>
<table id="tbl3" class="table2excel">
<tr>
<td>Product</td>
<td>Price</td>
<td>Available</td>
<td>Count</td>
</tr>
<tr>
<td>Bred</td>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
<tr>
<td>Butter</td>
<td>14</td>
<td>15</td>
<td >16</td>
</tr>
</table>
<hr>
<table id="tbl4" class="table2excel">
<tr>
<td>Product</td>
<td>Price</td>
<td>Available</td>
<td>Count</td>
</tr>
<tr>
<td>Bred</td>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
<tr>
<td>Awss</td>
<td>14</td>
<td>15</td>
<td >16</td>
</tr>
</table>
<button onclick="tablesToExcel(['tbl1','tbl2','tbl3','tbl4'], ['ProductDay1','ProductDay2','Sheet3','Sheet4'], 'TestBook.xls', 'Excel')">Export to Excel</button>
<script>
var tablesToExcel = (function() {
var uri = 'data:application/vnd.ms-excel;base64,'
, tmplWorkbookXML = '<?xml version="1.0"?><?mso-application progid="Excel.Sheet"?><Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">'
+ '<DocumentProperties xmlns="urn:schemas-microsoft-com:office:office"><Author>Axel Richter</Author><Created>{created}</Created></DocumentProperties>'
+ '<Styles>'
+ '<Style ss:ID="Currency"><NumberFormat ss:Format="Currency"></NumberFormat></Style>'
+ '<Style ss:ID="Date"><NumberFormat ss:Format="Medium Date"></NumberFormat></Style>'
+ '</Styles>'
+ '{worksheets}</Workbook>'
, tmplWorksheetXML = '<Worksheet ss:Name="{nameWS}"><Table>{rows}</Table></Worksheet>'
, tmplCellXML = '<Cell{attributeStyleID}{attributeFormula}><Data ss:Type="{nameType}">{data}</Data></Cell>'
, base64 = function(s) { return window.btoa(unescape(encodeURIComponent(s))) }
, format = function(s, c) { return s.replace(/{(\w+)}/g, function(m, p) { return c[p]; }) }
return function(tables, wsnames, wbname, appname) {
var ctx = "";
var workbookXML = "";
var worksheetsXML = "";
var rowsXML = "";
for (var i = 0; i < tables.length; i++) {
if (!tables[i].nodeType) tables[i] = document.getElementById(tables[i]);
for (var j = 0; j < tables[i].rows.length; j++) {
rowsXML += '<Row>'
for (var k = 0; k < tables[i].rows[j].cells.length; k++) {
var dataType = tables[i].rows[j].cells[k].getAttribute("data-type");
var dataStyle = tables[i].rows[j].cells[k].getAttribute("data-style");
var dataValue = tables[i].rows[j].cells[k].getAttribute("data-value");
dataValue = (dataValue)?dataValue:tables[i].rows[j].cells[k].innerHTML;
var dataFormula = tables[i].rows[j].cells[k].getAttribute("data-formula");
dataFormula = (dataFormula)?dataFormula:(appname=='Calc' && dataType=='DateTime')?dataValue:null;
ctx = { attributeStyleID: (dataStyle=='Currency' || dataStyle=='Date')?' ss:StyleID="'+dataStyle+'"':''
, nameType: (dataType=='Number' || dataType=='DateTime' || dataType=='Boolean' || dataType=='Error')?dataType:'String'
, data: (dataFormula)?'':dataValue
, attributeFormula: (dataFormula)?' ss:Formula="'+dataFormula+'"':''
};
rowsXML += format(tmplCellXML, ctx);
}
rowsXML += '</Row>'
}
ctx = {rows: rowsXML, nameWS: wsnames[i] || 'Sheet' + i};
worksheetsXML += format(tmplWorksheetXML, ctx);
rowsXML = "";
}
ctx = {created: (new Date()).getTime(), worksheets: worksheetsXML};
workbookXML = format(tmplWorkbookXML, ctx);
var link = document.createElement("A");
link.href = uri + base64(workbookXML);
link.download = wbname || 'Workbook.xls';
link.target = '_blank';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
})();
</script>
</body>
</html>
put all PHPExcel-1.8 code in third_party/PHPExcel-1.8
Create libraries/Excel.php as below. this is wrapper on PHPExcel lib.
require_once APPPATH . "/third_party/PHPExcel-1.8/Classes/PHPExcel.php";
class Excel extends PHPExcel {
public function __construct() {
parent::__construct();
}
private function parseFile($filePath){
//Create excel reader after determining the file type
$inputFileName = $filePath;
/** Identify the type of $inputFileName * */
$inputFileType = PHPExcel_IOFactory::identify($inputFileName);
/** Create a new Reader of the type that has been identified * */
$objReader = PHPExcel_IOFactory::createReader($inputFileType);
/** Set read type to read cell data onl * */
$objReader->setReadDataOnly(true);
/** Load $inputFileName to a PHPExcel Object * */
$objPHPExcel = $objReader->load($inputFileName);
//Get worksheet and built array with first row as header
$objWorksheet = $objPHPExcel->getAllSheets();
//excel with first row header, use header as key
$worksheet = array();
foreach ($objWorksheet as $key => $PHPExcel_Worksheet){
//excel sheet with no header
$worksheet[$key] = $PHPExcel_Worksheet->toArray(null, true, true, false);
}
return $worksheet;
}
}
Now You can use this Custom lib in your controller or model using CI's loader.
For example your controller having method like below.
function do_upload() {
$config['upload_path'] = './uploads/';
$config['allowed_types'] = 'application/vnd.ms-excel|application/x-csv|text/x-csv|text/csv|application/csv|application/excel|application/vnd.msexcel|application/vnd.openxmlformats-officedocument.spreadsheetml.sheet|application/zip|application/vnd.ms-excel|application/excel|xls|xlsx|csv';
$config['max_size'] = '10240'; // in KB
$this->load->library('upload', $config);
$this->upload->do_upload();
$this->load->library('Excel');
$DatainArray = $this->excel->parseFile($this->upload->upload_path . $this->upload->file_name);
//do some For loop and insert data to your database.enter code here
var_dumpt($DatainArray);
}

Simple UI testing a button click with karma and qUnit

I have figured out how to test my code with the karma test runner, but I cannot figure out how to test the UI features on a web page.
I have a simple calculator program (calculator.js):
window.onload = function () {
var okResult = /^.*(\+|\*|-|÷)\d$|^\d$|^.*\d((\+|\*|-|÷)|\d)$/,
i, tds = document.getElementsByTagName("td");
var setResult = function (t) {
document.getElementsByTagName("th")[0].innerHTML = t;
};
var appendResult = function (t) {
document.getElementsByTagName("th")[0].innerHTML += t;
};
var getResult = function () {
return document.getElementsByTagName("th")[0].innerHTML;
};
for (i = 0; i < tds.length; i++) {
tds[i].onclick = function () {
var r;
if (this.innerHTML == '=') {
setResult(eval(getResult().replace(/÷+?/g, '/')));
} else if (this.innerHTML == 'clr') {
setResult("0");
} else if (getResult() == '0') {
setResult(this.innerHTML);
} else {
appendResult(this.innerHTML);
}
if (!okResult.test(getResult())) {
r = getResult();
setResult(r.substring(0, r.length - 1));
}
};
}
};
With this simple table in the HTML DOM (calculator/index.html):
<table>
<tr>
<th id="results" colspan="4">0</th>
</tr>
<tr>
<td colspan="3"> </td>
<td>clr</td>
</tr>
<tr>
<td>7</td>
<td>8</td>
<td>9</td>
<td>÷</td>
</tr>
<tr>
<td>4</td>
<td>5</td>
<td>6</td>
<td>*</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>-</td>
</tr>
<tr>
<td>.</td>
<td>0</td>
<td>=</td>
<td>+</td>
</tr>
</table>
I want to test it by triggering click events on the cells found in the DOM. For example (calculator-spec.js):
test("Calculator initially displays 0", function () {
equal( $('td#results').text(), "0", "Initial display is 0" );
});
test("Calculator can add numbers", function () {
$('td:contains("1")').trigger('click');
$('td:contains("+")').trigger('click');
$('td:contains("1")').trigger('click');
$('td:contains("=")').trigger('click');
equal( $('td#results').text(), "2", "Initial display is 0" );
});
I am trying to automate testing with karma, and in my karma.conf.js file I have:
// frameworks to use
frameworks: ['qunit'],
// list of files / patterns to load in the browser
files: [
'http://code.jquery.com/jquery-1.10.2.min.js',
'**/Examples/Calculator/Complete/calculator.js',
'test/calculator/calculator-spec.js',
{pattern: '**/Examples/Calculator/Complete/index.html', watched: false, included: false, served: true}
],
How do I perform UI testing using karma. How can I simulate mouse and keyboard events and check the resulting DOM using either qUnit or jasmine?
I've had to use the DOM elements click method:
$('td:contains("1")')[0].click();

Resources