2

I have variable sets all my views in AppServiceProvider when I use that variable in the controller it says:

Undefined variable

Code

AppServiceProvider.php

View::composer('*', function ($view) {
    $ProductSettings = ProductSetting::all();
    foreach($ProductSettings as $psetting){
      $show_unavailable = $psetting->show_unavailable;
      $show_quantities = $psetting->show_quantities;
      $product_pagination = $psetting->pagination;
      $max_short_desc = $psetting->max_short_desc;
      $allow_delivery_time = $psetting->allow_delivery_time;
      $addtocart_on_attribute = $psetting->addtocart_on_attribute;
      $outofstock_lable = $psetting->outofstock_lable;
      $product_orderby = $psetting->orderby;
    }

    $view->with('show_unavailable', $show_unavailable);
    $view->with('show_quantities', $show_quantities);
    $view->with('product_pagination', $product_pagination);
    $view->with('max_short_desc', $max_short_desc);
    $view->with('allow_delivery_time', $allow_delivery_time);
    $view->with('addtocart_on_attribute', $addtocart_on_attribute);
    $view->with('outofstock_lable', $outofstock_lable);
    $view->with('product_orderby', $product_orderby);
});

Controller

//codes...

$products = Product::whereHas('categories', function ($query) use ($slug) {
  $query->where('slug', $slug);
})->paginate($product_pagination);

//codes...

Based on my database values product_pagination is set to 12 which means my code is like: ->paginate(12);

Question

Any idea why I get undefined error?

Update

table

one

13
  • Not sure, but maybe because $view->with doesn't give the controller the variable? Commented Feb 25, 2019 at 8:55
  • "View composers" sound like they'd only make variables accessible in ... views. Do you run that query in a view? Commented Feb 25, 2019 at 8:55
  • @kerbholz some of my variables i run in views this pagination specifically i need to run in controllers Commented Feb 25, 2019 at 8:57
  • @JustCarty do you have any better idea instead of I making same loop in each one of my controllers? Commented Feb 25, 2019 at 8:58
  • 2
    Also, your model loop in AppServiceProvider doesn't appear to make much sense because you set the variables in the loop, but only assign them to the view after the loop meaning only the last occurence (last row) is used... Commented Feb 25, 2019 at 8:58

1 Answer 1

2

Based on the comments, I am going to assume this will work:

$products = Product::whereHas('categories', function ($query) use ($slug) {
    $query->where('slug', $slug);
})->paginate(ProductSetting::first()->pagination);

Since you are only ever having one row in your product_settings table you can simply access the first row of that table, from there you can access any columns you need.


Edit 1

Based on the response, apparently the above is "too long".
The only other alternative I have for this question is the following:

App::singleton('product_settings', function () {
    return ProductSetting::first();
});

Write this method within the AppServiceProvider (or any provider of your choice), within the boot method.

Then, this can then be used anywhere with the following code:

app('product_settings')->pagination;
// or, more simply:
app('product_settings')-><some column name>;

If you think that there is still too much code then you can register your original variables using the same format with the singleton method and just add the -><some column name> after the first method call.


Edit 2

The above edit doesn't do anything different from the original solution and will still query with each call to the app method.

If you want to keep the database calls to one per controller, then you can store the ProductSetting::first() onto the BaseController:

class BaseController extends \Controller
{

    protected $product_settings;

    public function __construct() 
    {
        // Fetch the Site Settings object
        $this->product_settings = ProductSetting::first();
    }

}

Then within every controller you can call $this->product_settings->pagination.

Sign up to request clarification or add additional context in comments.

4 Comments

I know it can be happen in that way, the reason I was trying to get the value in AppServiceProvider was to avoid including my model to all controllers that I need this value and having long codes such as ProductSetting::first()->pagination do you have solution to get this value with simple variable only?
this singleton should I use it in appserviceprovider or creating new middleware etc.?
@mafortis Out of interest, which of the three methods did you go for? Edit 1?
currently I'm using solution 1 for 2 reasons: 1 I've read singleton in some cases will will return values repeatedly like foo will be foooo 2 I've read as well is not a good idea to pass variables into basicController as laravel provided view share for the very same reason. PS apparently viewShare is only works for blade templates and not controllers.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.