I was able to fetch certain data before but when I tried to add more code for pagination. It doesnt work anymore.
I need to paginate the data from API
error: "Trying to get property 'name' of non-object."
This is the result if I
if I dd($response) the results are:
{#274 ▼
+"pagelen": 10
+"next": "https://bitbucket.org/!api/2.0/repositories/spycetek?page=2"
+"values": array:10 [▶]
+"page": 1
+"size": 59
}
// I should paginate this. Here is my code for the controller.
public function index(Request $request, $page = 1)
{
$request = $this->client->get("https://bitbucket.org/!api/2.0/repositories/{$this->username}?page=" . $page,
[
'headers' => ['Authorization' => 'Bearer ' . $this->token]
]);
$response = json_decode($request->getBody()->getContents());
$repositories = $response->values;
$pagination = $response->pagelen;
$has_next_page = $pagination['has_next_page'];
$current_page = $pagination['page'];
$has_previous_page = $pagination['previous'];
$next_page = $pagination['next'];
return view('bitbuckets.repository')->with(compact('repositories'),
[ 'has_next_page' => $has_next_page,
'current_page' => $current_page, 'has_previous_page' => $has_previous_page,
'next_page' => $next_page]);
}
**//this is my blade.php file**
#extends('layoutss.layout')
#section('content')
<div class="container">
<div class="row" id="load" style="position: relative;">
<table class="table table-hover">
<thead>
<tr>
<th scope="col" class="text-secondary">Repositories</th>
</tr>
</thead>
<tbody>
#foreach($repositories as $key => $repository)
<tr>
<td>
{{$repository->name }}
</td>
</tr>
#if(isset($current_page))
<?php
$prev = $current_page - 1;
?>
#if(($has_next_page == true) && ($has_previous_page == false))
<li>Next</li>
#elseif(($has_next_page == false) && ($has_previous_page == true))
<li>Previous</li>
#elseif(($has_next_page == true) && ($has_previous_page == true))
<li>Previous</li>
<li>Next</li>
#endif
#endif
{{$repositories->links()}}
#endforeach
</tbody>
</table>
</div>
</div>
#endsection
and this is my code for routes.
Route::get('/{page?}', 'bb#index');
what is wrong with my codes
I messed up when it comes to pagination.
in blade.php was trying to display the list of all repositories and I wanted to paginate them. But I couldn't because of the error.
I have below JSON, from this I want to extract Skills where it is true.
[
{
"_id":"5de9f351baca28556c6a4b71",
"Name":"Harsha",
"Age":20,
"Gender":"M",
"Skills":{
"Java":"",
"Mule":true,
"Angular":""
}
},
{
"_id":"5de9f358baca28556c6a4b72",
"Name":"Anji",
"Age":21,
"Gender":"M",
"Skills":{
"Java":"",
"Mule":true,
"Angular":true
}
},
{
"_id":"5dea110297c2b65298b136e4",
"Name":"Abhi",
"Age":25,
"Gender":"M",
"Skills":{
"Java":"",
"Mule":true,
"Angular":""
}
}
]
I am able to print rest of the data using below code
<table *ngIf="formTemplate">
<tr>
<th *ngFor="let header of questionTitleArray" >{{header}}</th>
</tr>
<tr *ngFor="let data of surveyDataFromDB">
<ng-container *ngFor="let head of questionTitleArray">
<td>{{data[head]}}</td>
</ng-container>
</tr>
</table>
(Here JSON is "surveyDataFromDB")
Below is the output I am getting
Name Age Gender Skills
Harsha 20 M [object Object]
Anji 21 M [object Object]
Abhi 25 M [object Object]
I want Skills which are true in place of [object Object]. Please help.
You can first map your object to only have the truthy ones. You can use lodash pickBy.
mappedSurveyDataFromDB = this.surveyDataFromDB.map(
entry => ({...entry, Skills: _pickBy(entry.Skills, Boolean)}),
);
After change the template like this:
<table>
<tr>
<th *ngFor="let header of questionTitleArray">{{ header }}</th>
</tr>
<tr *ngFor="let data of mappedSurveyDataFromDB">
<ng-container *ngFor="let head of questionTitleArray">
<td *ngIf="head !== 'Skills'">{{ data[head] }}</td>
<td *ngIf="head === 'Skills'">
<ng-container *ngFor="let entry of (data[head] | keyvalue); let last = last">
{{ entry.key }}
<ng-container *ngIf="!last">, </ng-container>
</ng-container>
</td>
</ng-container>
</tr>
</table>
Stackblitz: https://stackblitz.com/edit/angular-ga7lqg
you can try like this
<table *ngIf="formTemplate">
<tr>
<th *ngFor="let header of questionTitleArray" >{{header}}</th>
</tr>
<tr *ngFor="let data of surveyDataFromDB">
<ng-container *ngFor="let head of questionTitleArray">
// here we are iterating a loop with keyvalue pipe bcs "Skills" is object
<span *ngIf="typeOf(data[head]) === 'object' else elsePart">
<td *ngFor="let j of data[head] | keyvalue">
{{j.key}} {{j.value}}
<td>
</span>
<ng-template #elsePart>
{{data[head]}}
<ng-template>
</ng-container>
</tr>
</table>
<table>
<tr>
<th *ngFor="let header of questionTitleArray">{{ header }} </th>
</tr>
<tr *ngFor="let data of surveyDataFromDB">
<ng-container *ngFor="let head of questionTitleArray">
<span *ngIf="checkType(data[head]) else elsePart">
<span *ngFor="let j of data[head] | keyvalue">
<td *ngIf="j.value==true">
{{j.key}}
</td>
</span>
</span>
<ng-template #elsePart>
<td>{{data[head]}}</td>
</ng-template>
</ng-container>
</tr>
</table>
in ts:
checkType(Ob:any)
{
if(typeof (Ob) === 'object')
return true;
else
return false;
}
You can process before render on ui, and create a comma seprated string of skill key on the basics of its value
let list=[{"_id":"5de9f351baca28556c6a4b71","Name":"Harsha","Age":20,"Gender":"M","Skills":{"Java":"","Mule":true,"Angular":""}},{"_id":"5de9f358baca28556c6a4b72","Name":"Anji","Age":21,"Gender":"M","Skills":{"Java":"","Mule":true,"Angular":true}},{"_id":"5dea110297c2b65298b136e4","Name":"Abhi","Age":25,"Gender":"M","Skills":{"Java":"","Mule":true,"Angular":""}}];
let result = list.map((o) => { return {...o, 'Skills': Object.entries(o.Skills).reduce((acc, i) => acc+= i[1] ? `${i[0]},`: '' , '').slice(0, -1) } });
console.log(result)
Or You can checkout this demo may this helps you
In template you can use KeyValuePipe to iterate on object i.e skills and show skill key only when its value is not falsy
<ng-container *ngFor="let entry of (data[head] | keyvalue); let last = last">
{{ entry.value ? entry.key: '' }}
<ng-container *ngIf="!last && entry.value">,</ng-container>
</ng-container>
Okey so you want to extract all the skills that are true and place them in a new object. From what I know there is not built in function to do this, however I wrote some code to to exactly this
var skills = {
Java: "",
Mule: true,
Angular: "",
Cpp: true,
Maja: false,
NodeJs: true
}
let keys = Object.keys(skills);
let trueSkills = {};
keys.forEach(keyValue => {
if (skills[keyValue] == true)
trueSkills[keyValue] = true;
});
console.log(trueSkills); // These are all the true skills
I hope this helps
Dealing with object keys based on their values can be complex in an Angular template. You could try to transform "Skills" into an array of strings. For example you could do it like this:
get formattedData() {
// this.data would be your json object
return this.data.map(i => ({...i, Skills: Object.keys(i.Skills).filter(j => i.Skills[j] === true)}))
}
This loops through every entry and transforms the skills object into an array with the skills.
This would return:
[
{
"_id":"5de9f351baca28556c6a4b71",
"Name":"Harsha",
"Age":20,
"Gender":"M",
"Skills":[
"Mule"
]
},
{
"_id":"5de9f358baca28556c6a4b72",
"Name":"Anji",
"Age":21,
"Gender":"M",
"Skills":[
"Mule",
"Angular"
]
},
{
"_id":"5dea110297c2b65298b136e4",
"Name":"Abhi",
"Age":25,
"Gender":"M",
"Skills":[
"Mule"
]
}
]
A minimal working example: Stackblitz
I would strongly advise against this method though, if you have a lot of entries as it would take a long time.
Skills attribute in your data is an Object. ngFor can only be used with Iteratable. Therefore first you should convert Skills to an Array. It can be done as below.
dataForView: any[];
prepareDataForView() {
this.dataForView = [...this.surveyDataFromDB];
this.dataForView.map(item => {
item.Skills = Object.keys(item.Skills).map(key => {
if (item.Skills[key]) {
return key;
}
});
});
}
And then you bind new array to View.
Find working Stackblitz Demo.
In my blade view, it is giving me an error Call to undefined method App\Student:: contains()
my controller
if($auth->user()->getRoleNames() == '["Parent"]'){
$id = $auth->user()->Parents_id;
$parent = ParentName::find($id);
$student = $parent->students;
$announce = AnnounceMent::get();
$roletype='parent';
return view('announcement.index',compact('student','roletype','announce'));
}
my view file
#foreach($announce as $ann)
#if($student->contains('id', $ann->student_id))
<tr>
<td>{{$i}}</td>
<td>{{$ann->announcement_type}}</td>
<td>
<?php $course = \App\Course::find($ann->course_id) ?>
{{$course->course_name}}
</td>
<td>
<?php $student = \App\Student::find($ann->student_id) ?>
{{$student['firstname'].' '.$student['lastname']}}
</td>
<td>{{$ann->description}}</td>
<td>
<a class="btn btn-success" href='{{ url("viewannounce/{$ann->id}") }}'>View</a>
</td>
</tr>
#endif
#php($i++)
#endforeach
this is my collection I am getting dd($students)
Collection {#595 ▼
#items: array:3 [▼
0 => Student {#596 }
1 => Student {#597 }
2 => Student {#598 }
]
}
contains is a collection method, you are calling it with a non-collection, if it will be App\Student::all()->contains('something') it will work fine, but App\Student::find(1)->contains('something') or App\Student::contains('something') will not work
Tinker results
>>> App\User::find(1)->contains('email')
BadMethodCallException with message 'Call to undefined method App/User::contains()'
>>> App\User::all()->contains('email')
=> false
>>> App\User::contains('email')
BadMethodCallException with message 'Call to undefined method App/User::contains()'
>>>
You can do
$student->id == $ann->student_id
in your situation, I guess.
I have a table AssetsAssignations, with hundreds of rows. In some cases, the user needs to select many rows with a checkbox, and change the "status" for all of them together.
In my controller, I have this function
public function editMultiple()
{
$assetStatuses = $this->AssetsAssignations->AssetStatuses->find('list');
$this->paginate = [
'contain' => ['Assets', 'AssetStatuses', 'Clients', 'Rooms'],
'sortWhitelist' => [
'Assets.model_number',
'Assets.serial_number',
'AssetStatuses.name',
'Clients.last_name',
'Rooms.name',
]
];
$assetsAssignations = $this->request->data;
$assetsAssignations_ids = array();
foreach($assetsAssignations as $a){
$assetsAssignations_ids[$a['id']] = $a['id'];
$this->AssetsAssignations->updateAll(
array('AssetAssignation.id' => $assetsAssignations_ids)
);
$this->Session->setFlash(__('Statsus is updated for the selcted entries!'));
}
debug($assetsAssignations);
$query = $this->AssetsAssignations->find()
->contain(['Assets', 'AssetStatuses', 'Clients', 'Rooms']);
$filter = $this->Filter->prg($query);
$assetsAssignations = $this->paginate($filter, ['maxLimit' => 10000, 'limit' => 10000]);
$this->set(compact('assetsAssignations', 'assetStatuses'));
$this->set('_serialize', ['assetsAssignations']);
}
In my edit_multiple.ctp, I use a javascript to filter the data. And I put this code:
<table class="hoverTable dataTable">
<thead>
<tr>
<th>Select</th><th>Model Number</th><th>Serial Number</th><th>Room</th><th>Client</th><th>Status</th>
</tr>
</thead>
</thead>
<?php foreach ($assetsAssignations as $assetsAssignation): ?>
<tr>
<td><input name="data[AssetsAssignations][id][]" value="<?= $assetsAssignation->id ?>" id="AssetsAssignationsId1" type="checkbox"></td>
<td><?= $assetsAssignation->has('asset') ? $assetsAssignation->asset->model_number : '' ?></td>
<td><?= $assetsAssignation->has('asset') ? $assetsAssignation->asset->serial_number : '' ?></td>
<td><?= $assetsAssignation->has('room') ? $assetsAssignation->room->name : '' ?></td>
<td><?= $assetsAssignation->has('client') ? $assetsAssignation->client->last_name . ', ' . $assetsAssignation->client->first_name: '' ?></td>
<td><?= $assetsAssignation->has('asset_status') ? $assetsAssignation->asset_status->name : '' ?></td>
</tr>
<?php endforeach; ?>
</table>
<legend><?= __('') ?></legend>
</div>
<?= $this->Form->create($assetsAssignation) ?>
<fieldset>
<div class="row">
<div class="col-xs-3"><?= $this->Form->input('asset_status_id', ['options' => $assetStatuses, 'empty' => true, 'label' => __('Change Status To')]) ?></div>
</div>
</fieldset>
<?= $this->Form->button(__('Submit')) ?>
<?= $this->Form->end() ?>
When I debug the result, checking 3 entries, I get this:
[
'data' => [
'AssetsAssignations' => [
'id' => [
(int) 0 => '411',
(int) 1 => '413',
(int) 2 => '415'
]
]
],
'asset_status_id' => '3'
]
My question is: How to pass the selected row IDs to the "Submit" button after selecting the checkboxes ?
Thanks in advance.
I think that what you want to do is something like
if($this->request->is('post')
{
$ids = $this->request->data('data.AssetsAssignations.id');
$asset_status_id = $this->request->data('asset_status_id');
$this->AssetsAssignations->updateAll(
['asset_status_id ' => $asset_status_id ]
['id IN' => $ids]
);
}
Based on what #Arilia suggested, tis worked for me. In my controller, function, I put this:
$this->request->data;
$data = $this->request->data;
debug($data);
if($this->request->is(['patch', 'post', 'put']))
{
$ids = $this->request->data('data.AssetsAssignations.id');
$asset_status_id = $this->request->data('asset_status_id');
$this->AssetsAssignations->updateAll(
['asset_status_id ' => $asset_status_id ],
['id IN' => $ids]
);
}
In my view, I put this:
<td><input type="checkbox" name="data[AssetsAssignations][id][]" value="<?= $assetsAssignation->id ?>" id="ApplicationId1" ></td>
I have massage error like this ErrorException
Undefined variable: posts (View: C:\xampp\htdocs\TA\resources\views\petani\index.blade.php). how i to solve it ?
Controller :
public function index(){
$post = Desa::all();
return view('petani.index',compact ('desas'));
}
Route :
Route::get('petani', 'BiodataController#index');
Index :
<?php
$no = 1;
?>
#foreach ($posts as $post)
<td>{{$no++}}</td>
<td>{{$post->nama}}</td>
<td>
<button type="button" class="btn"><a href="{{ URL::to('coba/test/'.$post->id.'/edit') }}" >Edit</a></button>
{{ Form::open(['url' => 'coba/test/'.$post->id, 'method' => 'DELETE']) }}
{{ Form::button('delete', ['type' => 'submit', 'class' => 'btn']) }}
{{ Form::close() }}
</td>
</tr>
#endforeach
instead of compact('desas'), type ['posts' => $post] and you're good to go