I Want to Put String on URL for HTTP CLIENT API LARAVEL 8 - laravel-8

my View :
<td>{{ $b = $booking->tanggal_pemesanan }}</td>
<td>CEK</td>
Route :
Route::get('/{b}', [TestController::class, 'index']);
my Controller:
public function index()
{
return Http::get('https://wetonizer-api.herokuapp.com/{b}');
}
did i do wrong? please help....

What is the actual return of $booking->tanggal_pemesanan?
Try using;
<td>CEK</td>
In your Controller;
index function should have ($b) to understand/know what is {b}
Then it should work

Related

Is it possible to render View based on OData query?

I've got Asp.Net Core application and there is an abstract controller.
I want to create a method, which will allow me to render list of entities as PartialView.
I've made it like this:
Should return PartialView with list of entities
[HttpGet]
[EnableQuery()]
public async Task<IActionResult> _List()
{
var result = _context.GetQueryByType<T>(); //returns DbSet<T> of whole table
return PartialView(await result.ToListAsync());
}
Example PartialView
#model IEnumerable<SomeClass>
<table class="table table-sm table-striped table-hover">
...
</table>
I want to call my method like this:
http://localhost:32769/SomeController/_List?$filter=id%20eq%2009515a38-2a1a-4a53-a4f8-e91e4dbd870b
And get filtered List view.
But anyway I get only whole table data.
The only solution for me is split this logic into 2 methods:
Get filtered Json data via standard Odata methods like:
http://localhost:32769/odata/SomeClass?$filter=ReleaseId%20eq%2011f28258-48cb-4c82-85e0-822850fd1f5c
Pass this data to method:
[HttpPost]
public IActionResult _List([FromBody] IEnumerable<T> entities)
{
return PartialView(entities);
}
I don't like this solution. Is there any possibility to filter my view data using OData queries?
Thx to ChristophLütjen.
.ApplyTo() is the solution.
Finally, working method looks like:
[HttpGet]
[EnableQuery]
public async Task<IActionResult> _List(ODataQueryOptions<T> queryOptions)
{
var result= (IQueryable<T>)queryOptions.ApplyTo(_context.GetQueryByType<T>());
return PartialView(await result.ToListAsync());
}
Also, it's very important to use ODataQueryOptions<T>, not ODataQueryOptions.
If you will use not common class, you will get an error, that method should return IEnumerable<T>, but not IActionResult.
Here is some documentation. Just want to pin it to the answer.
https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnet.odata.query.odataqueryoptions?view=odata-aspnetcore-7.0
Hope, that this info will be usefull for someone else.
upd:
Also I've found out, that it's not perfect soulution, if you want to use $expand method in your OData queries.
If you'll try to get type T of expanded query, you'll face the problem of SelectAllAndExpand type.
In this case this is the solution, I think it's not very beatiful and perfect, but it works:
[HttpGet]
[EnableQuery]
public IActionResult _List(ODataQueryOptions<T> queryOptions)
{
var validationSettings = new ODataValidationSettings
{
AllowedQueryOptions = AllowedQueryOptions.All,
AllowedFunctions = AllowedFunctions.All,
};
queryOptions.Validate(validationSettings);
IQueryable resultSet = queryOptions.ApplyTo(_context.GetQueryByType<T>(), new ODataQuerySettings());
List<T> resultList = new List<T>();
foreach (var item in resultSet)
{
if (item is T)
{
resultList.Add((T)item);
}
else if (item.GetType().Name == "SelectAllAndExpand`1")
{
var entityProperty = item.GetType().GetProperty("Instance");
resultList.Add((T)entityProperty.GetValue(item));
}
}
return PartialView(resultList as IEnumerable<T>);
}
Found it here: https://github.com/OData/WebApi/issues/1441

laravel unable to parse data

I want to go to page edit from PayAbleIndex to PayAbleEdit.
On laravel 5.4 i could use:
<button class="btn btn-primary">Edit</button>.
But currently I'm working on laravel 5.7 and i copy same code but laravel couldn't get any data from it.
My blade.php
#foreach($purchase as $data)
<tr>
<td>{{ $data->id }}</td>
<td>{{ $data->created_at }}</td>
<td>#if($data->import == 'y')Yes #else No #endif</td>
<td>Edit {{ $data->id }}</td>
</tr>
#endforeach
my controller
public function edit(accountPayAble $accountPayAble)
{
$pa = accountPayAble::where('purchases',$accountPayAble->id)->get();
return view('pages.payAbleEdit',['pa' => $pa]);
}
My accountPayAble Primary key are not ID but purchases
my account payable model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class accountPayAble extends Model
{
protected $table = "account_pay_ables";
protected $primaryKey = 'purchases';
public $timestamps =false;
public function purchase(){
return $this->belongsTo('App\purchase','purchases');
}
}
I think controller return array name should be purchase as below
public function edit(accountPayAble $accountPayAble)
{
$pa = accountPayAble::where('purchases',$accountPayAble->id)->get();
return view('pages.payAbleEdit',['purchase' => $pa]);
}
Check this and if it is not possible comment below.
Here is how generally edit method works
If you're passing id in edit method parameter in blade like this
Edit {{ $data->id }}
In this case route must have /{id}
// If you are using resource route then it will add /{id} in your edit parameter
Route::resource('payable', 'AccountPayAble');
// If you've defined custom route then
Route::get('/payable/edit/{id}','AccountPayAble#edit')->name('payable.edit');
In Your controller
// then you need to pass as well in your Controller method
public function edit(Request $request, $id)
{
$ap = AccountPayAble::find($id);
// OR
$ap = AccountPayAble::where('primary_key',$id)->first();
return view('pages.payAbleEdit',compact('ap'));
}
// If you've primary key other than id then define key into your model
protected $primaryKey = 'your_key_name';
I hope this helps.

Aurelia Dynamically Bound Value Converter

I'm running into an issue with Aurelia and am assuming that there is something I am missing.
I'm trying to create a 'generic' grid. I have removed a lot of the html to keep the example short, but the basic idea is this:
<template>
<require from="../value-converters"></require>
<table show.bind="rows.length">
<thead>
<tr>
<th repeat.for="columnDefinition of columnDefinitions">
${columnDefinition.displayName}
</th>
</tr>
</thead>
<tbody>
<tr repeat.for="row of rows">
<td repeat.for="columnDefinition of columnDefinitions">
<span if.bind="columnDefinition.isCurrency">${row[columnDefinition.propertyName] | numeralFormatter}</span>
<span if.bind="columnDefinition.isDate">${row[columnDefinition.propertyName] | dateFormatter}</span>
<span if.bind="!columnDefinition.isCurrency && !columnDefinition.isDate &&">${row[columnDefinition.propertyName]}</span>
</td>
</tr>
</tbody>
</table>
</template>
I want to be able to use the ValueConverters to help properly display certain types of column data. The above is currently working, but I want to have more value converters for other columns and the conditions will get unwieldy. My experience with Aurelia so far is that it offers fairly elegant solutions, but I have been unable to figure this one out as of yet.
I tried adding another property to the columnDefinition class like this formatter:string = undefined and then tried to create the spans like the following:
<span if.bind="columnDefinition.formatter">${row[columnDefinition.propertyName] | columnDefinition.formatter}</span>
<span if.bind="!columnDefinition.formatter">${row[columnDefinition.propertyName]}</span>
but the parser threw an error on the '.'.
Is there any way to achieve this? What is the 'aurelia-way' of dealing with this type of a problem.
Thanks in advance for any help that could be offered.
I ended up taking a similar approach to the one suggested by #Slyvain with a bit of a different twist:
import {DateValueConverter} from './date';
import {NumberValueConverter} from './number';
import {autoinject} from 'aurelia-framework';
#autoinject()
export class MetaValueConverter {
constructor(private date: DateValueConverter,
private number: NumberValueConverter) {
}
public toView(value, valueConverter, format) {
/* JUSTIFICATION: https://stackoverflow.com/questions/38898440/aurelia-dynamically-bound-value-converter#comment-65199423 */
/* tslint:disable:no-string-literal */
if (this[valueConverter] && this[valueConverter].toView) {
return this[valueConverter].toView(value, format);
} else {
return value;
}
}
public fromView(val, valueConverter, format) {
if (this[valueConverter] && this[valueConverter].fromView) {
return this[valueConverter].fromView(value, format);
} else {
return value;
}
}
}
Original code can be found here.
Hope this helps.
I followed #peinearydevelopment and went one step further again to create a fully dynamic value converter.
Usage is as follows ${myValue | dynamic:converterKey:converterArgs} or simply ${myValue | dynamic:converterKey} if no additional arguments are required. The converterKey is used to request a value converter that should be registered with the container. converterArgs is the array of arguments that you'd pass to the toView & fromView functions.
import { autoinject, Container } from 'aurelia-dependency-injection';
export type ValueConverterKey = new (...args: any[]) => object;
type ValueConverterFunc = (...args: any[]) => any;
interface ValueConverter {
toView?: ValueConverterFunc;
fromView?: ValueConverterFunc;
}
#autoinject()
export class DynamicValueConverter {
constructor(
private container: Container,
) { }
public toView(value: any, converterKey?: ValueConverterKey, ...converterArgs: any[]) {
if (!converterKey) {
return value;
}
return this.convertValueIfPossible(value, converterKey, converterArgs, 'toView');
}
public fromView(value: any, converterKey?: ValueConverterKey, ...converterArgs: any[]) {
if (!converterKey) {
return value;
}
return this.convertValueIfPossible(value, converterKey, converterArgs, 'fromView');
}
private convertValueIfPossible(value: any, converterKey: ValueConverterKey, converterArgs: any[], func: keyof ValueConverter) {
let converter = this.container.get(converterKey);
if (converter) {
let converterFunc = converter[func];
if (converterFunc) {
return converterFunc.call(converter, value, ...converterArgs);
}
}
return value;
}
}
Have you considered using a single <span> with a single general purpose converter that takes the column definition as a parameter and that delegates to the right converter? I think that would make the component markup simpler.
<span>${row[columnDefinition.propertyName] | formatCell:columnDefinition}</span>
And inside the formatter:
export class FormatCell {
toView(value, columnDefinition){
if(columnDefinition.isCurrency)
return new CurrencyConverter().toView(value);
if(columnDefinition.isDate)
return new DateConverter().toView(value);
return value;
}
}

Laravel Testing Error

I just started with learning how to test within Laravel. I came across some problems though..
I'm testing my controller and want to check if a View has a variable assigned.
My controller code:
class PagesController extends \BaseController {
protected $post;
public function __construct(Post $post) {
$this->post = $post;
}
public function index() {
$posts = $this->post->all();
return View::make('hello', ['posts' => $posts]);
}
}
And my view contains a foreach loop to display all posts:
#foreach ($posts as $post)
{{post->id}}
#endforeach
Last but not least my test file:
class PostControllerTest extends TestCase {
public function __construct()
{
// We have no interest in testing Eloquent
$this->mock = Mockery::mock('Eloquent', 'Post');
}
public function tearDown()
{
Mockery::close();
}
public function testIndex() {
$this->mock->shouldReceive('all')->once()->andReturn('foo');
$this->app->instance('Post', $this->mock);
$this->call('GET', '/');
$this->assertViewHas('posts');
}
}
Now comes the problem, when I run "phpunit" the following error appears:
ErrorException: Invalid argument supplied for foreach()
Any ideas why phpunit returns this error?
Your problem is here:
$this->mock->shouldReceive('all')->once()->andReturn('foo');
$this->post->all() (which is what you're mocking) should return an array, and that's what your view expects. You're returning a string.
$this->mock->shouldReceive('all')->once()->andReturn(array('foo'));
should take care of the error you have, though you'll then get an error of the "Getting property of non-object" type.
You could do this:
$mockPost = new stdClass();
$mockPost->id = 1;
$this->mock->shouldReceive('all')->once()->andReturn(array($mockpost));
You should mock the view as well:
public function testIndex() {
$this->mock->shouldReceive('all')->once()->andReturn('foo');
$this->app->instance('Post', $this->mock);
View::shouldReceive('make')->with('hello', array('posts', 'foo'))->once();
$this->call('GET', '/');
}

Url.Action is how to reformat URL

I am creating an MVC4 application.
In my contract controller overview page i have an Url.Action
int teller = 0;
foreach (var item in Model)
{
<a href="#Url.Action("Details", "Contract",new { id = teller })">
<tr>
<td>#Html.DisplayFor(modelItem => item.ContractMSFNo)</td>
<td>#Html.DisplayFor(modelItem => item.StageCode)</td>
<td>#Html.DisplayFor(modelItem => item.ValidFromView)</td>
<td>#Html.DisplayFor(modelItem => item.ValidToView)</td>
</tr>
</a>
teller++;
}
I need to pass the id. I am using id in the ActionLink details in Contract Controller
my controller is
public ActionResult Details(int id)
{
//code
return View(contract);
}
When i click on the link Url generated is
http://localhost:4826/Contract/Details/0
/0 is the id
i want my Url to be http://localhost:4826/Contract/Details
i know this can be acheived thru Html.Actionlink but it is my compulsion to use Url.Action. Can it be acheived with Url.Action
It can't be done by routing or ActionLink. But you may try to use session.
1) Add to your controller new method to save your id to session:
public JsonResult Save(int id)
{
Session["ID"] = id;
return Json("Success");
}
2) Add jQuery method to save data in session from View and delete parameter from Url.Action:
<a class="mylink" href="#Url.Action("Details", "Contract")"></a>
<script>
$(".mylink").click(function(){
var data = { id : teller}; //**teller is from your example
$.get("#Url.Action("Details", "Contract")", data)
});
</script>
3) Change your Details ActionResult to get id from session:
public ActionResult Details()
{
var id = (int)Session["ID"];
//code
return View(contract);
}
P.S: Ask your client, how he expects to give sombody external links. It will be impossible if url doesn't have a parameter. And it is very bad for SEO.
If you want your URL without the id parameter, simply don't pass it to the Url.Action() method, as follows:
#Url.Action("Details", "Contract")
If you add like {id=teller} then route automatically add id parameters end of the link. If you don't need id parameters for this url you need to remove
new { id = teller }
Final version like this
#Url.Action("Details", "Contract")
OK, reading this comment: "no actually there are many ids ... code is foreach (var item in Model) { ", I am not sure I understand what you really want to achieve. You are passing a parameter to the view, which can have only one value. Are you sure that you are not looking for something like:
foreach (var item in Model)
{
<a href="#Url.Action("Details", "Contract",#item.ID>
...
}
instead? The fact the ID is visible or not in the URL seems to be another problem, no ?