I refactored my code, even so, I'm still generated the same Error Exception. I will show the old code and the refactored code. I'll also provided the error message generated by Laravel. in addition to the spaghetti code I received when troubleshooting the error with dd().
I have my own custom made helper functions that I'm using. It's a class and is injected into the home page Controller as a dependency. My helper function is then passed to Laravel Blade as a variable named helper.
The goal is to have my navigation links change to a different color if it is the currently selected and active link to that page.
When I apply the $helper variable to the first link, I get my desired result. However, the $helper variable generates the Undefined Variable $helper Error Exception on all the other links.
I used dd() to troubleshoot the error. I received a output of spaghetti code as a result.
Utilities/Helper class example - my custom helper function
/*
* Original
*/
<?php
namespace App\Utilities;
class Helper
{
public static function activePage(string $pageUrl): string
{
$requestUri = $_SERVER['REQUEST_URI'];
return $requestUri === $pageUrl ? "color=var(--sky)" : "color=var(--mud)";
}
}
/*
* Refactored
*/
<?php
namespace App\Utilities;
class Helper
{
public static function activePage(string $pageUrl): string
{
return Request::is($pageUri) ? "style=color:var(--sky)" : "style=color:var(--mud)";
}
}
Controller/Home Action example
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\BaseController;
use App\Utilities\Helper;
use Illuminate\View\View;
class Home extends BaseController
{
public function __construct(
private Helper $helper,
){}
public function index(): View
{
return view('home', [
'helper' => $this->helper::class,
]);
}
}
Laravel Blade Template home page example
<!-- Original -->
<li class="nav-links">
<a href="{{ url('/') }}" style="{{ $helper::activePage('/') }}">Home</a>
<a href="{{ url('/services') }}" style="{{ $helper::activePage('/services') }}">Services</a>
<a href="{{ url('/clients') }}" style="{{ $helper::activePage('/clients') }}">Clients</a>
<a href="{{ url('/about') }}" style="{{ $helper::activePage('/about') }}">About</a>
<a href="{{ url('/blog') }}" style="{{ $helper::activePage('/blog') }}">Blog</a>
<a href="{{ url('/contact') }}" style="{{ $helper::activePage('/contact') }}" class="contact-link">Contact</a>
</li>
<!-- Refactored -->
<li class="nav-links">
<a href="{{ url('/') }}" {{ $helper::activePage('/') }}>Home</a>
<a href="{{ url('/services') }}" {{ $helper::activePage('/services') }}>Services</a>
<a href="{{ url('/clients') }}" {{ $helper::activePage('/clients') }}>Clients</a>
<a href="{{ url('/about') }}" {{ $helper::activePage('/about') }}>About</a>
<a href="{{ url('/blog') }}" {{ $helper::activePage('/blog') }}>Blog</a>
<a href="{{ url('/contact') }}" {{ $helper::activePage('/contact') }} class="contact-link">Contact</a>
</li>
<!-- Also tried: no error occurred, but was not able to get the color to change to var(--sky) on the second link -->
<li class="nav-links">
<a href="{{ url('/') }}" {{ Request::is('/') ? "style=color:var(--sky)" : "style=color:var(--mud)" }}>Home</a>
<a href="{{ url('/services') }}" {{ Request::is('/services') ? "style=color:var(--sky)" : "style=color:var(--mud)" }}>Services</a>
<a href="{{ url('/clients') }}">Clients</a>
<a href="{{ url('/about') }}">About</a>
<a href="{{ url('/blog') }}">Blog</a>
<a href="{{ url('/contact') }}" class="contact-link">Contact</a>
</li>
Image of Error Exception
Generated unformatted spaghetti code when using dd()
Sfdump = window.Sfdump || (function (doc) { doc.documentElement.classList.add('sf-js-enabled'); var rxEsc = /([.*+?^${}()|\[\]\/\\])/g, idRx = /\bsf-dump-\d+-ref[012]\w+\b/, keyHint = 0 <= navigator.platform.toUpperCase().indexOf('MAC') ? 'Cmd' : 'Ctrl', addEventListener = function (e, n, cb) { e.addEventListener(n, cb, false); }; if (!doc.addEventListener) { addEventListener = function (element, eventName, callback) { element.attachEvent('on' + eventName, function (e) { e.preventDefault = function () {e.returnValue = false;}; e.target = e.srcElement; callback(e); }); }; } function toggle(a, recursive) { var s = a.nextSibling || {}, oldClass = s.className, arrow, newClass; if (/\bsf-dump-compact\b/.test(oldClass)) { arrow = '▼'; newClass = 'sf-dump-expanded'; } else if (/\bsf-dump-expanded\b/.test(oldClass)) { arrow = '▶'; newClass = 'sf-dump-compact'; } else { return false; } if (doc.createEvent && s.dispatchEvent) { var event = doc.createEvent('Event'); event.initEvent('sf-dump-expanded' === newClass ? 'sfbeforedumpexpand' : 'sfbeforedumpcollapse', true, false); s.dispatchEvent(event); } a.lastChild.innerHTML = arrow; s.className = s.className.replace(/\bsf-dump-(compact|expanded)\b/, newClass); if (recursive) { try { a = s.querySelectorAll('.'+oldClass); for (s = 0; s < a.length; ++s) { if (-1 == a[s].className.indexOf(newClass)) { a[s].className = newClass; a[s].previousSibling.lastChild.innerHTML = arrow; } } } catch (e) { } } return true; }; function collapse(a, recursive) { var s = a.nextSibling || {}, oldClass = s.className; if (/\bsf-dump-expanded\b/.test(oldClass)) { toggle(a, recursive); return true; } return false; }; function expand(a, recursive) { var s = a.nextSibling || {}, oldClass = s.className; if (/\bsf-dump-compact\b/.test(oldClass)) { toggle(a, recursive); return true; } return false; }; function collapseAll(root) { var a = root.querySelector('a.sf-dump-toggle'); if (a) { collapse(a, true); expand(a); return true; } return false; } function reveal(node) { var previous, parents = []; while ((node = node.parentNode || {}) && (previous = node.previousSibling) && 'A' === previous.tagName) { parents.push(previous); } if (0 !== parents.length) { parents.forEach(function (parent) { expand(parent); }); return true; } return false; } function highlight(root, activeNode, nodes) { resetHighlightedNodes(root); Array.from(nodes||[]).forEach(function (node) { if (!/\bsf-dump-highlight\b/.test(node.className)) { node.className = node.className + ' sf-dump-highlight'; } }); if (!/\bsf-dump-highlight-active\b/.test(activeNode.className)) { activeNode.className = activeNode.className + ' sf-dump-highlight-active'; } } function resetHighlightedNodes(root) { Array.from(root.querySelectorAll('.sf-dump-str, .sf-dump-key, .sf-dump-public, .sf-dump-protected, .sf-dump-private')).forEach(function (strNode) { strNode.className = strNode.className.replace(/\bsf-dump-highlight\b/, ''); strNode.className = strNode.className.replace(/\bsf-dump-highlight-active\b/, ''); }); } return function (root, x) { root = doc.getElementById(root); var indentRx = new RegExp('^('+(root.getAttribute('data-indent-pad') || ' ').replace(rxEsc, '\\$1')+')+', 'm'), options = {"maxDepth":1,"maxStringLength":160,"fileLinkFormat":false}, elt = root.getElementsByTagName('A'), len = elt.length, i = 0, s, h, t = []; while (i < len) t.push(elt[i++]); for (i in x) { options[i] = x[i]; } function a(e, f) { addEventListener(root, e, function (e, n) { if ('A' == e.target.tagName) { f(e.target, e); } else if ('A' == e.target.parentNode.tagName) { f(e.target.parentNode, e); } else { n = /\bsf-dump-ellipsis\b/.test(e.target.className) ? e.target.parentNode : e.target; if ((n = n.nextElementSibling) && 'A' == n.tagName) { if (!/\bsf-dump-toggle\b/.test(n.className)) { n = n.nextElementSibling || n; } f(n, e, true); } } }); }; function isCtrlKey(e) { return e.ctrlKey || e.metaKey; } function xpathString(str) { var parts = str.match(/[^'"]+|['"]/g).map(function (part) { if ("'" == part) { return '"\'"'; } if ('"' == part) { return "'\"'"; } return "'" + part + "'"; }); return "concat(" + parts.join(",") + ", '')"; } function xpathHasClass(className) { return "contains(concat(' ', normalize-space(@class), ' '), ' " + className +" ')"; } a('mouseover', function (a, e, c) { if (c) { e.target.style.cursor = "pointer"; } }); a('click', function (a, e, c) { if (/\bsf-dump-toggle\b/.test(a.className)) { e.preventDefault(); if (!toggle(a, isCtrlKey(e))) { var r = doc.getElementById(a.getAttribute('href').slice(1)), s = r.previousSibling, f = r.parentNode, t = a.parentNode; t.replaceChild(r, a); f.replaceChild(a, s); t.insertBefore(s, r); f = f.firstChild.nodeValue.match(indentRx); t = t.firstChild.nodeValue.match(indentRx); if (f && t && f[0] !== t[0]) { r.innerHTML = r.innerHTML.replace(new RegExp('^'+f[0].replace(rxEsc, '\\$1'), 'mg'), t[0]); } if (/\bsf-dump-compact\b/.test(r.className)) { toggle(s, isCtrlKey(e)); } } if (c) { } else if (doc.getSelection) { try { doc.getSelection().removeAllRanges(); } catch (e) { doc.getSelection().empty(); } } else { doc.selection.empty(); } } else if (/\bsf-dump-str-toggle\b/.test(a.className)) { e.preventDefault(); e = a.parentNode.parentNode; e.className = e.className.replace(/\bsf-dump-str-(expand|collapse)\b/, a.parentNode.className); } }); elt = root.getElementsByTagName('SAMP'); len = elt.length; i = 0; while (i < len) t.push(elt[i++]); len = t.length; for (i = 0; i < len; ++i) { elt = t[i]; if ('SAMP' == elt.tagName) { a = elt.previousSibling || {}; if ('A' != a.tagName) { a = doc.createElement('A'); a.className = 'sf-dump-ref'; elt.parentNode.insertBefore(a, elt); } else { a.innerHTML += ' '; } a.title = (a.title ? a.title+'\n[' : '[')+keyHint+'+click] Expand all children'; a.innerHTML += elt.className == 'sf-dump-compact' ? '▶' : '▼'; a.className += ' sf-dump-toggle'; x = 1; if ('sf-dump' != elt.parentNode.className) { x += elt.parentNode.getAttribute('data-depth')/1; } } else if (/\bsf-dump-ref\b/.test(elt.className) && (a = elt.getAttribute('href'))) { a = a.slice(1); elt.className += ' sf-dump-hover'; elt.className += ' '+a; if (/[\[{]$/.test(elt.previousSibling.nodeValue)) { a = a != elt.nextSibling.id && doc.getElementById(a); try { s = a.nextSibling; elt.appendChild(a); s.parentNode.insertBefore(a, s); if (/^[@#]/.test(elt.innerHTML)) { elt.innerHTML += ' ▶'; } else { elt.innerHTML = '▶'; elt.className = 'sf-dump-ref'; } elt.className += ' sf-dump-toggle'; } catch (e) { if ('&' == elt.innerHTML.charAt(0)) { elt.innerHTML = '…'; elt.className = 'sf-dump-ref'; } } } } } if (doc.evaluate && Array.from && root.children.length > 1) { root.setAttribute('tabindex', 0); SearchState = function () { this.nodes = []; this.idx = 0; }; SearchState.prototype = { next: function () { if (this.isEmpty()) { return this.current(); } this.idx = this.idx < (this.nodes.length - 1) ? this.idx + 1 : 0; return this.current(); }, previous: function () { if (this.isEmpty()) { return this.current(); } this.idx = this.idx > 0 ? this.idx - 1 : (this.nodes.length - 1); return this.current(); }, isEmpty: function () { return 0 === this.count(); }, current: function () { if (this.isEmpty()) { return null; } return this.nodes[this.idx]; }, reset: function () { this.nodes = []; this.idx = 0; }, count: function () { return this.nodes.length; }, }; function showCurrent(state) { var currentNode = state.current(), currentRect, searchRect; if (currentNode) { reveal(currentNode); highlight(root, currentNode, state.nodes); if ('scrollIntoView' in currentNode) { currentNode.scrollIntoView(true); currentRect = currentNode.getBoundingClientRect(); searchRect = search.getBoundingClientRect(); if (currentRect.top < (searchRect.top + searchRect.height)) { window.scrollBy(0, -(searchRect.top + searchRect.height + 5)); } } } counter.textContent = (state.isEmpty() ? 0 : state.idx + 1) + ' of ' + state.count(); } var search = doc.createElement('div'); search.className = 'sf-dump-search-wrapper sf-dump-search-hidden'; search.innerHTML = '
0 of 0<\/span>
After reading the code, is there anything you think would cause an error to occur?
The Solution to Laravel Undefined Variable Error Exception. To keep it very simple. Each controller renders a view. So if you're working on the home page nav links and each controller renders a view for each of those links. You'll receive an Error Exception if you try to echo a variable on the other links and missing the fact that you didn't passed the variable through your other controllers first. I'll provide code examples below.
Helper Function / Dependency
class helper
{
public static function pleaseHelp(string $param): string
{
return // your code
}
}
Controllers
namespace App\Controllers;
use App\Utilities\Helper;
// The variable 'set' works on the rendered home page and the home nav link.
// It will not work on the other nav links without causing the Error Exception.
class Home
{
public function __construct(
private Helper $pleaseHelp,
){}
public function index(): View
{
return view('home', [
'set' => $this->pleaseHelp,
]);
}
}
// In order to get your nav links working on the other pages, you'll need
// to inject your Helper Dependency into your other controller class.
class About
{
// Helper Dependency here...
return view('about', [
'set' => $this->pleaseHelp,
]);
}
class Contact
{
// Helper Dependency here too...
return view('contact', [
'set' => $this->pleaseHelp,
]);
}
Laravel Blade / html
// Link about & contact can now read the variable $set and load the page without error
<nav>
<a href="{{ url('/') }}" class="{{ $set::pleaseHelp('/') }}">Home</a>
<a href="{{ url('about') }}" class="{{ $set::pleaseHelp('about') }}">About</a>
<a href="{{ url('contact') }}" class="{{ $set::pleaseHelp('contact') }}">Contact</a>
</nav>