Undefined Method/Variable problems on my 2nd system

Published 1 week ago by splendidkeen

Hey everybody, I am not able to address methods I create within my models/controllers on my 2nd system.

For example: Business.php (Model)

 public function getCompanyName(){
        return  $this->company_name;
 }

Controller:

public function getPartnerProfile($company_name){

        $business = Business::where('company_name', $company_name)->first();

        if(!$business){
            abort(404);
        }

        return view('partner.profile.index')
            ->with('company_name', $business);
    }
}

Within view:

{{ $business->getCompanyName() }} 

Error:

Undefined variable: business

Just can't figure it out

Best Answer (As Selected By splendidkeen)
kfirba

@splendidkeen If I understand correctly, in your navigation code, you check for an authenticated partner and if there is one, you try to add some navigation links.

I think that within that context, the Auth::user() call is actually returning a Business model. Can you try changing this line:

{{  Auth::user()->business->getCompanyName() }}

To:

{{  Auth::user()->getCompanyName() }}

If it does not work, can you post here what does Auth::user() returns? You should be able to figure this out by calling:

get_class(Auth::user())
kfirba
kfirba
1 week ago (203,855 XP)

@splendidkeen Hey

You called your variable company_name and not business:

->with('company_name', $business);

You should use it as follows:

{{ $company_name->getCompanyName() }}

Or just change the way you refer to your variable:

return view('partner.profile.index')->with('business', $business);

// or yet better (in my opinion):
return view('partner.profile.index', compact('business'));
splendidkeen

Thank you so much!

splendidkeen

Sorry, again @kfirba Why does this not work?

{{ Auth :: business()->getCompanyName() }}

splendidkeen

Err: Method business does not exist.

kfirba
kfirba
1 week ago (203,855 XP)

@splendidkeen There is no business method on the Auth facade. Are you actually trying to do something like:

Auth::user()->business->getCompanyName();
splendidkeen

This results in:

Trying to get property of non-object 
splendidkeen

@kfirba

Maybe I made some mistake with my guards and providers?

Guard:

'partner' => [ 'driver' => 'session', 'provider' => 'business', ],

Provider:

'business' => [ 'driver' => 'eloquent', 'model' => App\Models\Business::class, ],

splendidkeen

Hey again @kfirba

Now my system fails with the err:

Call to a member function getCompanyName() on null

..when I address my method within the navigation:

{{ Auth::user()->business->getCompanyName() }}

Do I have to wrap the method within an Auth check or add middleware to this route, unless the user is authenticated? Btw, zhat is still on my 2nd system.

Sorry for the spam, but your help would be just great.

kfirba
kfirba
1 week ago (203,855 XP)

@splendidkeen Hey.

Well, you can indeed check if the user is authenticated. However, it seems like your issue is not with the user not being authenticated but with your authenticated user not being associated with a business.

Since your error message indicate that you call getCompanyName() method on a null, it means that Auth::user()->business is returning null which means that the authenticated user does not have a business relationship.

Also, if you are using Laravel 5.5, you can use the optional() method which will act as a null object pattern:

{{ optional(Auth::user()->business)->getCompanyName() }}

You can read more about the optional() method here: https://laravel.com/docs/5.5/helpers#method-optional

splendidkeen

First, thank you again @kfirba. Where would one setup or address this relation? Maybe I forgot something over there?

Maybe within my BusinessAuthController at the sign-in method?

public function postSignin(Request $request){
        
        //Validate form data
        $this -> validate ($request, [
            'email' => 'required',
            'password' => 'required',
        ]);


        //Attempt to Log-in User
        //Auth::attempt($credentials, $remember);


        // if successful, then redirect to their intended location
        if(Auth::guard('partner')->attempt(['email' => $request->email, 'password' => $request->password], $request->remember)){
            
            return redirect()->route('partner.index');
        }
        // if unsuccessfull, then redirect back to the login with the form data
        return redirect()->back()->withInput($request->only('email', 'remember'))->with('info', 'Could not sign in with those details');
    }

splendidkeen
  • within my Handler.php file:
 protected function unauthenticated($request, AuthenticationException $exception)
    {
        if ($request->expectsJson()) {
            return response()->json(['error' => 'Unauthenticated.'], 401);
        }

        $guard = array_get($exception->guards(), 0);

        switch ($guard) {
            case 'partner':
                $login = 'busauth.signin';
                break;
            
            default:
                $login = 'auth.signin';
                break;
        }

        return redirect()->guest(route('$login'));
    }

Should be correct? Sorry again for the spam @kfirba

kfirba
kfirba
1 week ago (203,855 XP)

@splendidkeen I'm not sure what you are trying to do but calling Auth::user() will return the currently authenticated user for the given guard or the default guard defined in your config file.

I'm assuming that there is a Business model that has a user_id column.

On your User model (or any other model you use for authentication), you should have a business relationship:

class User extends Authenticatable
{
    // ...
    
    public function business()
    {
        return $this->hasOne(Business::class); 
    }
}

Now when you access the property business on Auth::user(), Laravel will detect that there is a business relationship defined and will automatically fetch that relationship for you.

splendidkeen

@kfirba Sorry for the misunderstanding. So what I am trying to do is, input content from the authenticated Business into the navigation, as we talked about earlier, which returns into null. I created a Business.php Model to control methods and more for my second system, meaning Users which access the app as Partners/Businesses.

Business.php

class Business extends Model implements AuthenticatableContract
{
    use Authenticatable;

    protected $guard = 'partner';
    
    protected $table = 'business';
    
    
    protected $fillable = [
        
        'email', 
        'company_name', 
        'password',
        'zip',
        'city',
        'country',
        'genre',
    ];

     
    protected $hidden = [
        'password', 
        'remember_token',
    ];


    public function getCompanyName(){
        return  $this->company_name;
    }
 
}

When I login with a Partner account I created, it works until I address methods within my navigation:

{{  Auth::user()->business->getCompanyName() }}

This is the navigation ()=<> :


(ul) class="nav navbar-nav navbar-right"
        @if (Auth::guard('partner')->check())
        (li)(a) {{  Auth::user()->business->getCompanyName() }}(/a)(/li)
        (li)(a) href="{{route('busauth.signout')}}"  id="navnav">Log out (/a)(/li)
        @else
                    
        @endif
(/ul)

It's weird, I can for example address

{{$business->getCompanyName() }}

within my main page, but within my navigation its spits an err with undefined variable business, again.

This is my User Model for the User Login:

User.php

class User extends Model implements AuthenticatableContract
{
    use Authenticatable;
    
    protected $table = 'users';
    
    
    protected $fillable = [

        'username', 
        'email', 
        'password',
        'first_name',
        'last_name',
        'location',
        'status',
        'avatar',
    ];

     
    protected $hidden = [
        'password', 
        'remember_token',
    ];

}

I am very thankful for your patience and help.

kfirba
kfirba
1 week ago (203,855 XP)

@splendidkeen If I understand correctly, in your navigation code, you check for an authenticated partner and if there is one, you try to add some navigation links.

I think that within that context, the Auth::user() call is actually returning a Business model. Can you try changing this line:

{{  Auth::user()->business->getCompanyName() }}

To:

{{  Auth::user()->getCompanyName() }}

If it does not work, can you post here what does Auth::user() returns? You should be able to figure this out by calling:

get_class(Auth::user())
splendidkeen

@kfirba Thank you again for solving my problem. You are great.

Please sign in or create an account to participate in this conversation.