Introduction
I'm using this Add-on for Visual Studio Code.
When creating relations with it. My views seem not working. I get an error in the browser (see below).
Laravel Snippets ID: onecentlin.laravel5-snippets Beschreibung:
Laravel snippets for Visual Studio Code (Support Laravel 5 and above)
Version: 1.13.0 Herausgeber: Winnie Lin Link zum Visual Studio
Marketplace: https://marketplace.visualstudio.com/items?itemName=onecentlin.laravel5-snippets
My Model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Person extends Model
{
use HasFactory;
protected $fillable = [];
/**
* Get the phone associated with the Person
*
* #return \Illuminate\Database\Eloquent\Relations\HasOne
*/
public function phone(): HasOne
{
return $this->hasOne(Phone::class);
}
}
Error shown by the browser, when calling the view
TypeError Return value of App\Models\Person::phone() must be an instance of
App\Models\HasOne, instance of
Illuminate\Database\Eloquent\Relations\HasOne returned (View:
C:\Users\MusaSaglam\componenttest\resources\views\test\index.blade.php)
My view
<x-layout>
<main class="main" id="top">
<div class="container" data-layout="container">
<script>
var isFluid = JSON.parse(localStorage.getItem('isFluid'));
if (isFluid) {
var container = document.querySelector('[data-layout]');
container.classList.remove('container');
container.classList.add('container-fluid');
}
</script>
<x-nav.admin-nav/>
<div class="content">
<x-nav.admin-nav-top/>
<h1>People</h1>
#foreach ($people as $person)
<h2>{{ $person->id }}</h2>
<h2>{{ $person->phone->number }}</h2>
#endforeach
</div>
</div>
</main>
</x-layout>
But if I remove : HasOne after public function phone() in my model. Everything works fine.
Two questions
Why does the Snippet adds : HasOne. What is the benefit of this?
Does not make it easier for users like me using the snippet without : HasOne?
I'm a beginner and I could not understand why the tutorials did not work.
You can refer to the type declaration https://www.php.net/manual/en/language.types.declarations.php
Why does the Snippet add: HasOne. What is the benefit of this?
It’s the return type of method and it’s standard so the VS code add-on is giving you the snippet(code) which follows the industry standards.
Does not make it easier for users like me using the snippet without : HasOne? I'm a beginner and I could not understand why the tutorials did not work.
This snippet will work don’t worry about it. Just declare the HasOne before the class initialization like use Illuminate\Database\Eloquent\Relations\HasOne and it should work.
By the way type hinting is optional so a snippet will work if you just remove :HasOne(return type of method). which you already tried.
Related
In laravel 8 how can i do login registration in same page , Problem is in both form email and password are same . valiadation error shows in both form .
Thanks in advance
If you want to have multiple forms with the same input names on one page you need to take a look at named error bags.
If you are using FormRequests, it's quite easy. You can set a custom ErrorBag on the specific FormRequest.
<?php
use Illuminate\Foundation\Http\FormRequest;
class LoginFormRequest extends FormRequest
{
protected $errorBag = 'loginForm';
}
<?php
use Illuminate\Foundation\Http\FormRequest;
class RegisterFormRequest extends FormRequest
{
protected $errorBag = 'registerForm';
}
Earlier you have been used to use something like this in your blade files:
<div>{{ $errors->first('email') }}</div>
This uses the default ErrorBag. But in our case, we have overwritten the bag with our custom ones. The syntax changes a little bit if you want to access them. Here's how.
<div>{{ $errors->loginForm->first('email') }}</div>
<div>{{ $errors->registerForm->first('email') }}</div>
I am learning how to use vue with laravel. I have basic loops working well to pull direct model relationships, but I can't figure out how to access model methods in a loop. Many of my Larvel models have basic information formulated with a method pulling data from related models. I've tried to research it and think the answer might be some combination of eager loading, preformating the answer as a json response or maybe something with axios, but the snipits I've found aren't clear on what goes where, or what needs to be in place for them to work correctly. I've tried both eager loading and using a json response and neither has worked. I can access methods in simple vue components that are just text, but not in a loop where the variable isn't part of the page.
Example: I want to use Vue to display a list of ingredients on a recipe's page. The ingredient "title" is a method pulling the information from a related model.
RecipeController.php
public function show(Recipe $recipe)
{
$ingredients = $recipe->ingredients;
$view = $this->view('recipes.show');
//(variable in the view, variable defined in current function)
$view->with('recipe', $recipe);
$view->with('ingredients', $ingredients);
return $view;
}
Recipe.php
public function ingredients()
{
return $this->hasMany('App\Models\Ingredient', 'recipe_id', 'recipe_id');
}
Ingredient.php
public function title()
{
$title = $this->item->title();
return $title;
}
public function vueTitle()
{
$title = Ingredient::title()->get();
return response()->json($title );
}
Recipes/show.php
<div>
<ul>
<li
is="test-li"
v-for="ingredient in {{ $ingredients }}"
v-bind:key="ingredient.ingredient_id"
v-bind:title= "ingredient.vueTitle"
v-bind:id="ingredient.ingredient_id"
></li>
</ul>
</div>
I'd prefer to reuse the same methods, but created a new one to try converting to json first but that didn't work (or I'm doing it wrong). I tried eager loading, but it either did nothing, or generated an error (Call to a member function on null) if I tried to eager load the specific method. I've tried various combinations of binding and not binding the title component. I've also tried title= "{{ingredient->title()}}" but that syntax errors.
How can I get the result of the Laravel method in a Vue loop?
After more searching, I found this post which described how to add an accessor to a model. Doing so allowed me to access my custom method as if it were a standard direct relationship. It was a straightforward modification and will reduce complexity in a number of places. I made the following modifications:
Ingredient.php
Added the get..Attribute() function and appended the array
...
protected $table = 'ingredients';
...
protected $appends = array('title');
// Access methods as direct relationships
public function getTitleAttribute()
{
return $this->title();
}
Recipes/show.php
Bound the title prop to the ingredient title as if it were a direct relationship.
<div>
<ul>
<li
is="test-li"
v-for="ingredient in {{ $ingredients }}"
v-bind:key="ingredient.ingredient_id"
v-bind:title= "ingredient.title"
v-bind:id="ingredient.ingredient_id"
></li>
</ul>
</div>
Another example, hope one may find it helpful:
Model.php
/**
* Accessor for Age.
*/
protected $appends = ['age'];
public function getAgeAttribute()
{
return Carbon::parse($this->attributes['dob'])->age;
}
VueFile.vue
<td>
<span v-bind:age="user.age"> {{user.age}} </span>
</td>
I´m a beginner starting with Laravel. I´m trying to show a question made on this website.
Here is the Controller page:
public function show($id)
{
//Use the model to get 1 record from the database
$question = $Question::findOrFail($id);
//show the view and pass the record to the view
return view('questions.show')->with('question', $question);
}
I have included at the top of the file:
use App\Question;
Here is my blade page:
#section('content')
<div class="container">
<h1> {{ $question->title }} </h1>
<p class="lead">
{{ $question->description }}
</p>
<hr />
</div>
#endsection
In the model I have not defined anything since I don´t need to specify any special rule. And finally here is the Route:
Route::resource('questions', 'QuestionController');
I got the error "ErrorException Undefined Variable: Question" and supposedly the error is on:
$question = $Question::findOrFail($id);
I´m looking forward to your observations.
Kind Regards.
You just need to change the controller section
public function show($id)
{
//Use the model to get 1 record from the database
$question = Question::findOrFail($id); // here is the error
//show the view and pass the record to the view
return view('questions.show')->with('question', $question);
}
Explanation:- You are going to use a variable $Question that is not defined. This is the basic PHP error, not the laravel issue.
However, You are using the "App\Question" model class not a sperate variable.
I'm excited that the October CMS recently added back-end functionality for sorting records in the list view. But I'm having some trouble getting it to work. The documentation is here. I've followed the direction like so:
In my controller, I implemented the ReorderController:
<?PHP namespace BTruchan\Team\Controllers;
use Backend;
use BackendMenu;
use BackendAuth;
use Backend\Classes\Controller;
use System\Classes\SettingsManager;
class Members extends \Backend\Classes\Controller
{
public $implement = [
'Backend.Behaviors.FormController',
'Backend.Behaviors.ListController',
'Backend.Behaviors.ReorderController'
];
public $formConfig = 'config_form.yaml';
public $listConfig = 'config_list.yaml';
public $reorderConfig = 'config_reorder.yaml';
public $requiredPermissions = ['btruchan.team.manage'];
public function __construct()
{
parent::__construct();
BackendMenu::setContext('BTruchan.Team', 'team');
}
public function index()
{
$this->makeLists();
$this->makeView('reorder');
}
}
?>
I've created the reorder view file (reorder.htm) which contains:
<?= $this->reorderRender() ?>
My config_reorder.yaml file contains:
# ===================================
# Reorder Behavior Config
# ===================================
# Reorder Title
title: Reorder Members
# Attribute name
nameFrom: name
# Model Class name
modelClass: BTruchan\Team\Models\Members
# Toolbar widget configuration
#toolbar:
# Partial for toolbar buttons
# buttons: reorder_toolbar
You'll notice that the reorder_toolbar partial is commented out. That's because I really don't know what's supposed to go in that toolbar. I haven't been able to find any documentation that shows the contents for the _reorder_toolbar.htm file.
Unsurprisingly, with the code commented out, it throws an error:
Undefined variable: reorderToolbarWidget
Some additional information:
It was suggested that I read up on list toolbars here.
So I added the following toolbar partial (named _reorder_toolbar.htm):
<div data-control="toolbar">
<a
href="<?= Backend::url('btruchan/team/members/create') ?>"
class="btn btn-primary oc-icon-plus">
New Team Member
</a>
<button
class="btn btn-default oc-icon-trash-o"
disabled="disabled"
onclick="$(this).data('request-data', {
checked: $('.control-list').listWidget('getChecked')
})"
data-request="onDelete"
data-request-confirm="Delete Team Member: Are you sure?"
data-trigger-action="enable"
data-trigger=".control-list input[type=checkbox]"
data-trigger-condition="checked"
data-request-success="$(this).prop('disabled', false)"
data-stripe-load-indicator>
Delete
</button>
</div>
But I'm still getting an error:
Undefined variable: reorderToolbarWidget
/var/www/terrasearch/public/modules/backend/Behaviors/reordercontroller/partials/_container.htm
line 1
The code, in October CMS, which that error message is referring is:
<?php if ($reorderToolbarWidget): ?>
<!-- Reorder Toolbar -->
<div id="<?= $this->getId('reorderToolbar') ?>" class="reorder-toolbar">
<?= $reorderToolbarWidget->render() ?>
</div>
<?php endif ?>
<!-- Reorder List -->
<?= Form::open() ?>
<div
id="reorderTreeList"
class="control-treelist"
data-control="treelist"
I've tried to trace this error down. It seems like, in \public\modules\backend\behaviors\ReorderController.php, the reorder() function is not being called, which means that the prepareVars() function is also not being called. This prevents the following code from being executed:
$this->vars['reorderToolbarWidget'] = $this->toolbarWidget;
ReorderController.php:: makeToolbarWidget() is being called and seems to be OK. I've checked $this->toolbarWidget, and it seems to contain perfectly good data. (It isn't NULL).
The ReorderController is a behavior, so it's meant to be called as a controller destination (e.g. example.com/backend/btruchan/team/members/reorder). It's not coded to be called as a view the way you have it in your index function.
In the ReorderController source, the reorder function is the only method that calls the prepareVars protected function which is the only place that the reorderToolbarWidget is defined for the page. That prepareVars function isn't available from the host controller.
So, rather than try to create a view with $this->makeView('reorder');, create a toolbar button in the _list_toolbar.htm partial that points to the reorder destination url. For example:
<div data-control="toolbar">
New Member
Reorder Members
</div>
When you click on the "Reorder Members" button, you'll be directed to a new page with the records that can be reordered.
You can use the _reorder_toolbar.htm partial to add anything you want at the top of the reorder page. Or, not use it at all.
I have a project which is using laravel4 and its blade view engine. Occasionally I have had the need to call controller methods via a view file to output dynamic data; incidentally this time its a call to a method that generates javascript code for the page. Regardless of whether this is the best way to go about things is a moot point atm as I am simply upgrading from L3 to L4.
My View is similar to:
#extends('en/frontend/layouts/default')
{{-- Page title --}}
#section('title')
Page Title
#parent
#stop
{{-- Page content --}}
#section('pageContent')
...
#stop
{{-- Scripts --}}
#section('scripts')
<?php echo CaseStudy::script(); ?>
#stop
I have set up CaseStudy to load via the laravel facades and the class at current is simply:
class CaseStudy
{
public function display()
{
}
/**
* Returns the javascript needed to produce the case study
* interactivity
*
* #return \Illuminate\View\View|void
*/
public function script()
{
$language = \Config::get('app.locale');
$scriptElementView = $language . '.frontend.elements.casestudy_script';
if ( ! \View::exists($scriptElementView))
{
$scriptElementView = "Training::" . $scriptElementView;
}
return \View::make($scriptElementView, array());
}
}
It would appear that echoing the response of CaseStudy::script is what is causing the blank body; however with no further error message I do not know what is going on. I assume that this is because my static CaseStudy's instance of View is conflicting with the instance being used by the blade engine. How would I go about having CaseStudy::script() returning a string form of the rendered view?
Thank you.
In your view
{{-- Scripts --}}
#section('scripts')
{{ CaseStudy::script() }}
#stop
In your library
class CaseStudy
{
public function script()
{
$string = "your script here";
return $string;
}
}
Note - CaseStudy should really be a "library" or "helper" or something. Not a controller - that does not really conform to MVC approach.