Re-use the static method called in Blade template - laravel-4

Let's say I have a static method called Message::countNew() and that method used to count the new message from database.
And then, I want to display the number of new messages in 1 page twice.
<!-- On the top menu -->
<nav>{{ Message::countNew }} new message(s)</nav>
<!-- On the other location of page (still on the same page) -->
<div>You have {{ Message::countNew }} message(s)
If I do that, will Laravel call the static method (Message::countNew()) twice? Or does it have some sort of mechanism which maybe the second call will fetch the value from some kind of cache.
Or is there a best practice for this case?
Thanks!

yes, it will execute the query twice. executing query is not duty of view layer.
you should execute your queries in controller or in a view composer.
there's a handy tool to trace how your laravel app works.
https://github.com/barryvdh/laravel-debugbar

Related

Passing data from one view to another in Laravel

I have a Controller that parses an XML and returns a view with a list of names and URLs.
return view('view_1',compact('myList'));
View_1 will have a form with parameters method="POST" action="goToView_2"
Then I get some information from my view_2 through a POST, but I still want to keep $myList so that view_2 view uses it aswell.
How do I pass $myList from the first view to the next through a controller?
It sounds like you're trying to have multi-step form of some kind.
I would store the data in the session and easily access it in the second controller or in the view (although not recommended).
https://laravel.com/docs/5.4/session#using-the-session
PS. I personally love using the global session helper.

Convention for a controller that generates a view from several models

In Sails.js, a route is set up against a controller method which can render a view. For the most part, this is straightforward, i.e. you could set up a GET /users route that points to UserController.find (which is usually set up automatically anyway).
However, say the home page of a blog renders the 10 most recent posts in the main section and a column with a list of authors and categories. The controller method has to fetch posts, authors, and categories before rendering the view and sending it back to the client. Clearly, a method like this doesn't really belong in PostController, AuthorController, or CategoryController.
What's the best thing to do in this situation? Create a controller for rendering views that rely on data from multiple models? Is there a good name for such a controller?
Thanks!
What I would do (this is purely opinion-based) is creating a PageController and create an action for each page you'd want.
For your home page example you can create a home action, get whatever you need and then render it with res.ok() (if everything is fine).
Another option would be to use Sails as a pure API and use HTTP requests (Ajax) or sockets to get your data in JSON. If you want to do so, I'd advise you to use a front end framework such as Angular, Ember, React...
By the way you could also create actions rendering HTML in your existing controllers and create a route to hit them through Ajax requests and just print them in your page. I'd prefer the 2nd solution because it takes full advantage of the Blueprint API (you don't need new controller or action whatsoever).
As Yann pointed out, this answer has to be a little opinionated. It seems that you are using the views system and not building a single page application. For the home page, I would go for an IndexController.js file with a home(req, res) action.
// api/controllers/IndexController.js
module.exports = {
home: function (req, res) {
// Retrieve all the information you need
// Take care about managing the asynchronous calls before rendering the view
return res.view('homepage');
}
};
Declare the route
// config/routes.js
module.exports.routes = {
'get /': 'IndexController.home'
}
Create the view in views/homepage.ejs.

How can I get HTML element value inside Angular JS conroller while the page is getting loaded

Let me tel the scenario where I am stuck, I will try to explain simply rather than telling the actual.
1st : I am on page 1. Where few subjects are there with unique names.
2nd : I will click on one subject, which will call an struts2 action (lets call it ActionA)at back end with the unique subject name as a request parameter(Request type = GET).
3rd : Action A will only redirect to "Tutorial page".
4th : While loading it will make an AJAX call to another Struts2 action (lets call it ActionB), which will return JSON containing tutorials for that Subject.
Problem: As I am calling ActionA first and passing the subject name which is just redirecting the page to some other page. On page load I am calling another action to get the JSON. I am not able to get the request parameter value at ActionB that is the one which is returning JSON.
Note: I am using Struts2-JSON plugin thats why not need two actions, one for redirecting the page another for getting the JSON at page load.
Solution tried: I have tried to get the request parameter value that is the Subject name, putting a hidden field in the Tutorial page. But unable to get the value from inside the Angular JS controller.
Here is the example for a shared Service: http://plnkr.co/edit/P2ItVj20RYCJVjdIaXfY
But you are right if you reload the page this doesn't work. I think your scenario needs tweaking if you want to use angular or any other single page framework for that matter. One purpose of single page applications is to minimize reloads, preferable none. If your action A only returns a template where you then want to input the result of action B, I recommend looking at ngRoute or uiRouter, where you define a template (result of action A) and a controller for that view. This template than replaces a section of your page (ng-view) with the new template. If both are new to you I would recommend looking at uiRouter, it is similar but it gives you a lot more possibilities. Both provide a "resolve" function where you can load your action B before the page is rendered.
Code from plunker
angular.module("app", [])
.controller("MainController", ['SharedService', function(SharedService) {
var vm = this;
//bind to service
vm.service = SharedService;
}]);
Service
angular.module("app")
.factory("SharedService", [function() {
var service = {
id: "test"
}
return service;
}]);

Laravels flash session stores data twice

this ones a head ache! From my understanding of laravel's flash method for sessions, once it has been set then called, it will be destroyed...
Session::flash( 'key', $data );
somewhere down the line
{{ Session::get( 'key' ) }}
I am using this for form validation. Now when the form does not validate, the application displayed the error, if I amend the form and post again, the database updates, the details are displayed correctly, but the error appears again! This is the same for if I post the form that doesn't validate, it displays the error, but if I then click the navigation link for the same page, it displays again!
Anyone come across this?
regards
Luke
I had this problem once when I did a return view() / return View::Make when it should be a return redirect()->route() in my Controller#update method.
Since Laravel 5.1, you can use the now() method which will only affect the current request :
Session::now('key', 'message');
or
session()->now('key', 'message');
Out of the laravel docs:
The flash method stores an item in the session that will expire after the next request. It's useful for storing temporary data like status or error messages.
This means, it's available at the current and also the next request. It does not get flushed automatically if you access it. To do so, use Session::flush('key');.
Session Flash preserves the session data for 2 requests because it was meant to be used during redirection.
However, I've came across a use case where I do want to use flash for just 1 request in the next view and found an easy way to do it, which is to pull from the session rather than get it. The Session::pull() gets the session data and removes from the session.
#if (Session::has('message'))
<div class="alert alert-message">{{Session::pull('message'}}</div>
#endif
Hope this helps!
It's probably some other issue with your code, if you could share your code it would help us get a better insight into this issue.
You can use the below code snippet to Flash Error messages to your laravel blade template.
#if (Session::has('message'))
<div class="alert alert-success">{{Session::get('message')}}</div>
#endif
I once had similar issue because i used Session::reflash() in my controller.
Ensure you don't have Session::reflash() somewhere in your controller or anywhere in your application, as it flashes whole session... use example: Session::keep(array('username', 'email')); to reflashing only A Subset Of Flash Data
An easy way to flash a message once when you are creating a view (and not redirecting) is:
Session::flash($key, $value);
Session::push('flash.old', $key);
Refer here.
The flash method is meant for storing the data for the next request. Ideally after flashing the data to the session you should be redirecting to a new route. (This is what the accepted answer suggests.)
But if you are not redirecting you can call the forget method after displaying the session in your blade template:
{{ session()->flash('key') }}
#php
session()->forget('flash-info');
#endphp

How do i page using forms with the Codeigniter framework?

I'm using the Codeigniter framework and am in the process of creating a registration form. The registration process is completed in multiple steps- for which I've created different views.
What I have a problem with is making the controller read that I've continued to a new step. I tried solving this by posting the form to index.php/controller/2 but as I reach the page I get a 404 error stating
The page doesn't exist.
I've loaded the URI helper so I don't quite understand where the problem lies.
All help is very much appreciated
By submitting the form to index.php/controller/2 you're effectively saying
Load /application/controllers/Controller.php
Instantiate class Controller
Run Controller::2()
I suspect you don't have a method named 2, and you want to pass two as an argument to a method which handles step 1. Which might be /controller/register or similar.
You need to submit your form to index.php/controller/method/2 and inside method check which step you're on using $this->uri->segment(2)
Ideally, create a different method for each step as it'll better separate the logic. For example
class Registration {
function step_1() {}
function step_2() {}
}
Which will allow you to call index.php/registration/step_1/ and index.php/registration/step_2/ for example.
You may also wish to use the Session class to set variables indicating which stages are complete to prevent people skipping to other stages by typing in the URL.

Resources