Can't display mongodb collection to view Laravel - laravel

I'm using MongoDb and Laravel for a demo.
I'm trying to get the collection from MongoDb and display it to view in Laravel.
Here is my model:
class Account extends Eloquent
{
public function getAllAccount() {
$account = DB::connection('mongodb')->collection('Account')->get();
return $account;
}
}
Here is my Controller:
class AccountController extends Controller
{
public function index() {
$acc = new Account();
$data = $acc -> getAllAccount();
return view('account', $data);
}
}
And then, I display it to view:
#if(isset($data))
#foreach($data as $dataValue)
<tr>
<td>{{ $dataValue->_id }}</td>
<td>{{ $dataValue->avail_balance }}</td>
<td>{{ $dataValue->last_activity_date }}</td>
<td>{{ $dataValue->open_date }}</td>
<td>{{ $dataValue->pending_balance }}</td>
<td>{{ $dataValue->cust_id }}</td>
<td>{{ $dataValue->open_branch_id }}</td>
<td>{{ $dataValue->open_emp_id }}</td>
<td>{{ $dataValue->product_id }}</td>
</tr>
#endforeach
#endif
I set Controller in web.php:
Route::get('/account', 'AccountController#index');
But when I run this, it return nothing, just a blank page.
How I can fix that?
Thank you very much!
UPDATE:
I use dd($data) in my controller and here is all my collection:

You've got to send the data back in a format the page can take.
In the index() method, change:
return view('account', $data);
to
return view('account', compact ('data');
To be pretty, you can use ->with() as well, but I like compact since you can move a lot of variables easily.

Related

Value correlation from multiple tables in laravel

I have two tables. One employees and one timesheets
I would like to have correct name at the result but different ID. If you see the result I have the same name everywhere.
How can make the code to fixed my challenge?
Thank you.
In controller I have this code
$profile = ['no' => Auth::user()->no];
$timesheets = Timesheet::where($profile)->select('*')->orderBy('created_at','DESC')->get();
foreach ($timesheets as $employee) {
$emp = ['identification' => $employee->identification];
$oneemployee = Employees::where($emp)->select('*')->orderBy('created_at','DESC')->get();
}
return view('contractor.employees.timesheets', compact('timesheets', 'oneemployee'));
and in blade I have
#foreach ($timesheets as $row1)
<tr>
<td>#</td>
#foreach ($oneemployee as $row2)
<td>{{ $row2->fname}}</td>
<td>{{ $row2->lname}}</td>
#endforeach
<td>{{ $row1->identification}}</td>
<td>{{ $row1->week}}</td>
<td>{{ $row1->year}}</td>
</tr>
#endforeach
According to your commit, I suggest the following solution
If you want dispay timesheet with employees you can use eager loading.
For example:
In your controller:
$profile = ['no' => Auth::user()->no];
$timesheets = Timesheet::where($profile)->with("employees")->select('*')->orderBy('created_at','DESC')->get();
return view('contractor.employees.timesheets', compact('timesheets'));
In your Timesheet model add hasOne relation to Employee:
public function employee(){
return $this->hasOne(Employee::class,'identification','identification')
}
And your view:
#foreach ($timesheets as $timesheet)
<tr>
<td>#</td>
<td>{{ $timesheet->employee->fname}}</td>
<td>{{ $timesheet->employee->lname}}</td>
<td>{{ $timesheet->identification}}</td>
<td>{{ $timesheet->week}}</td>
<td>{{ $timesheet->year}}</td>
</tr>
#endforeach

How to calculate using data from get() in controller

I have some data from a table and I'm doing an eloquent get for it. So far from what I know is when using get(), I need to loop it first using foreach to get the data.
My question is how to move my logic code to controller? so I just need to pass it to view. Because I'm doing it on blade directly
Bellow is my controller, I'm just simply get a data from database:
$attendances = Attendance::where('company_id', Auth::user()->company_id)->get();
#foreach ($attendances as $attendance)
// How to move this php code to my controller?
#php
$work_hour_start = $attendance->work_hour_start;
$attendance_time = \Carbon\Carbon::parse($attendance->attendance_time)->format('H:i:s');
$tolerance = \Carbon\Carbon::parse($attendance_time)->addMinutes($attendance->late_tolerance);
if ($tolerance > $work_hour_start) {
$is_late = 'Late';
} else {
$is_late = 'On Time';
}
#endphp
<tr>
<td>{{ $attendance->employee->name }}</td>
<td>{{ Carbon\Carbon::parse($attendance->attendance_time)->format('H:i:s') }}</td>
<td>{{ $attendance->location_library->location_name }}</td>
<td>{{ $is_late }}</td>
</tr>
#endforeach
I want my blade to be clean, but I don't know how to do that.
You could add attendance_time to the $casts property and make tolerance/is_late accessors in the Attendance Model
# Attendance.php
class Attendance extends Model
{
...
protected $casts = [
'attendance_time' => 'datetime',
];
...
public function getToleranceAttribute()
{
return $this->attendance_time->addMinutes($this->late_tolerance);
}
public function getIsLateAttribute()
{
return $this->tolerance > $this->work_hour_start
? 'Late'
: 'On time';
}
...
}
#foreach ($attendances as $attendance)
<tr>
<td>{{ $attendance->employee->name }}</td>
<td>{{ $attendance->attendance_time->format('H:i:s') }}</td>
<td>{{ $attendance->location_library->location_name }}</td>
<td>{{ $attendance->is_late }}</td>
</tr>
#endforeach
Just do it, move the logic to your controller and set it up in your $attendances collection. Something like this:
$attendances = Attendance::where('company_id', Auth::user()->company_id)->get();
foreach ($attendances as $key => $attendance){
$attendances[$key]->attendance_time = \Carbon\Carbon::parse($attendance->attendance_time)->format('H:i:s');
if (\Carbon\Carbon::parse($attendances[$key]->attendance_time)->addMinutes($attendance->late_tolerance > $attendance->work_hour_start) {
$attendances[$key]->setAttribute('is_late', 'Late');
} else {
$attendances[$key]->setAttribute('is_late', 'On Time');
}
}
return view('your-view', ['attendances' => $attendances]);
Now it will be able to iterate on your template:
#foreach ($attendances as $attendance)
<tr>
<td>{{ $attendance->employee->name }}</td>
<td>{{ $attendance->attendance_time }}</td>
<td>{{ $attendance->location_library->location_name }}</td>
<td>{{ $attendance->is_late }}</td>
</tr>
#endforeach

Laravel Aggregates query not working according to group by

On POS when I place any order it stored the order detail according to the product id on order_details table. I want to sum the quantity order according to product id.
Order Detail table : id, order_id, product_id, total, created_at, updated_at
Product Controller :
public function index()
{
$orderdetail = DB::table('order_details')
->select('quantity', DB::raw('sum(quantity) as sum'))
->groupBy('product_id')
->havingRaw('SUM(quantity)')
->get();
$products = Product::latest()->with('category', 'supplier', 'orderdetail')->get();
return view('admin.product.index', compact('products', 'orderdetail'));
}
On Product Model:
class Product extends Model
{
protected $dates = [
'buying_date', 'expire_date',
];
public function category()
{
return $this->belongsTo(Category::class);
}
public function supplier()
{
return $this->belongsTo(Supplier::class);
}
public function orderdetail()
{
return $this->belongsTo('App\OrderDetail', 'id', 'product_id');
}
}
}
But it does not show anything on Blade.
on Blade :
#foreach($products as $key => $product)
<tr>
<td>{{ $key + 1 }}</td>
<td>{{ $product->name }}</td>
<td>
<img class="img-rounded" style="height:35px; width: 35px;" src="{{ URL::asset("storage/product/".$product->image) }}" alt="{{ $product->name }}">
</td>
<td>{{ $product->category->name }}</td>
<td>{{ $product->supplier->name }}</td>
<td>{{ $product->code }}</td>
<td>{{ $product->buying_date->toFormattedDateString() }}</td>
<td>{{ number_format($product->buying_price, 2) }}</td>
<td>{{ number_format($product->selling_price, 2) }}</td>
<td>{{ $product->product_unit }}</td>
<td>{{ $product->product_unit - $product->sum }}</td>
<td>{{ $product->sum }}</td>
<td>DLT</td>
</tr>
#endforeach
This is the result of dd on $products and $orderdetail
It aggregates the value not showing the blade template. how I show it on the blade or there any problem on model or blade? please help.
Here I solved via this way
on Controller
public function index()
{
$orderdetail = DB::table('order_details')
->select('quantity', DB::raw('sum(quantity) as soldunit'))
->groupBy('product_id')
->get();
$products = Product::latest()->with('category', 'supplier', 'orderdetail')->get();
return view('admin.product.index', compact('products', 'orderdetail'));
}
and on Model, I have slightly Changed
public function orderdetail()
{
return $this->hasMany('App\OrderDetail','product_id', 'id')->selectRaw('order_details.*,sum(quantity) as soldunit')->groupBy('product_id');
}
after this, to access soldunit on the blade I used this one
{{ $product->orderdetail->sum('soldunit') }}
If you want to access sum of a column via a defined relationship, you need to add it during your main query:
$products = Product::with('category', 'supplier')->with(['orderdetail' => function($query){
$query->select('id', 'product_id', 'quantity', DB::raw('sum(quantity) as sum'));
}])->get();

Accessing further data

So I am accessing an external API and I am trying to display this data
https://i.stack.imgur.com/Yop0I.png
and everything was fine so far as you can see
https://i.stack.imgur.com/L3hXq.png
using this code
<tr v-for="cv_output in cv_outputs" :key="cv_output.id">
<td>{{ 'teste' }}</td>
<td>{{ cv_output['id'] }}</td>
<td>{{ cv_output['last-modified-date'] }}</td>
<td>{{ cv_output['output-category']['value'] }}</td>
<td>{{ cv_output['output-category']['code'] }}</td>
<td>{{ cv_output['output-type']['value'] }}</td>
<td>{{ cv_output['output-type']['code'] }}</td>
<td>{{ cv_output['other-output'] }}</td>
but as soon as I try to go further such as
{{ cv_output ['other-output']['title'] }}
the data stops displaying in the table and in the console i get the following:
TypeError: Cannot read property 'title' of null
which doesn't make any sense I think. Any idea why?
Controller method:
public function getRemoteOutputs()
{
$science = Auth::user()->science_id;
$client = new Client(['headers' => ['Accept' => 'application/json']]);
$request = $client->get(
'https://url_to_the_api/'.$science.'/degree',
[
'auth' => ['client', 'secret'],
]
);
$data = $request->getBody()->getContents();
return $data;
}
I #Helpinghand is correct, one of the records is missing other-output.
Try:
<td>
<span v-if="cv_output['output-type']">{{ cv_output['output-type']['title'] }}</span>
<span v-else>No Output Type Title</span>
</td>
Try this:
{{ cv_output ['other-output'] ? cv_output ['other-output']['title']: ''}}
This will return the other-output->title if it exists, if not it should return nothing without error. (you can put whatever you want in the single quotes there if you want something like 'not available' as default)

Laravel need data from two different collections in for each

I have a for each loop to iterate over the collection of records. It has the user_id, but not the other user credentials. I created another collection of user. How do I include this in my iteration?
Controller
public function index(Request $request, $id)
{
$thoughts = Thought::where('id', $id)->orderBy('created_at', 'desc')->paginate(100)->get();
$user = User::where('id', $thoughts->user_id);
return view('backend.pages.thought_list', compact('thoughts, user'));
}
View
#foreach ($thoughts as $thought)
<tr>
<td class="col-md-1">{{ $user->username}} <span class="user_id_thought">ID - {{ $user->user_id}}</span></td>
<td class="col-md-1">{{ $thought->response }}</td>
<td>{{ $thought->thought_type }}</td>
<td>{{ $thought->id }}</td>
</tr>
#endforeach
How do I display my users variable in the loop. Or is there a better way of doing this.
Eager Loading is the perfect use case for your requirement in my opinion.
e.g.
$thoughts = Thought::with('user')->get();
foreach ($thoughts as $thought) {
echo $thought->user->name;
}
For more details see: https://laravel.com/docs/5.6/eloquent-relationships#eager-loading

Resources