Laravel + Vue Page Redirection - laravel-5

How can I redirect to a page when I try to create something that it has to be done in another page?
Example:
I created page that will ask the details for books and saved it to the database. The first page will ask the user to put the cover of the book, title and description. I used Vue Component for the page and axios to save it in the database. I used this code window.location.href = "/create-book/" to redirect to another page which will be the user can start writing and when he saved it, it will save on the current book he was making.
right now Im stuck in this
Vue Component
axios.post('/admin/saveBook', formData).then(function(result){
// console.log(result.data)
window.location.href = "/admin/write-book";
});
and In my controller I used this
Controller
return response()->json($book);
My goal is just to make a one whole page for writing the content of the book. Thanks!

You might look into using Vue Router, specifically Dynamic Route Matching and Programmatic Navigation.
In your router, you'd have a dynamic path for your books.
routes: [
{
// dynamic segments start with a colon
path: '/books/:id',
name: 'book',
component: Book
}
]
Then in your component, you'd navigate to the book on creation.
axios.post('/admin/saveBook', formData).then(function(result) {
this.$router.push({ name: 'book', params: { id: result.data.book.id }});
});
If you need info for the book when you navigate to it, you can either fetch it using the id when mounted or pass the book as a prop on navigation. See Passing Props to Route Components.

Related

Inertia.JS reload props after post request

I am currently pretty confused why Inertia.js is not reloading or rerendering my page.
I have a form that could be filled, once submitting this will execute:
Inertia.post("/ban", ban);
This will redirect to a POST in the web.php of my Laravel.
That looks like this:
Route::post("/ban", [Speler::class, "ban"]);
This redirects to a class called "Speler", in there is a function called "ban".
Once done some SQL statements it will execute this return:
return Redirect::route("speler", [$steam])->with("success", "Ban doorgevoerd!");
This will go back to the web.php, and go to the route speler with the session data "success".
That redirect goes into the web.php:
Route::get("/speler/{steam}", [PageLoader::class, "speler"])->name("speler");
This one goes to the PageLoader controller, and execute the "speler" function.
But here it gets weird, this will return a Inertia::render of the same page the person was on, but would need to add another prop, or change the prop. (so i can show a popup with te text that it succeeded)
return Inertia::render("Panel/Speler",
["steamNaam" => $steamNaam, "discord" => $discord, "karakterAantal" => $karakterAantal, "karakters" => $karakters, "sancties" => $sanctiesReturn, "punten" => $aantalPunten, "steamid" => $steamid, "success" => $melding]
);
The "success" prop contains $melding that simply contains a string.
But for some reason it doesn't seem to re-render the page, the form stays filled, and the props are the same.
Does someone have a solution?
If you setup your form with the form helper, you can reset the form on a successful post like this:
form.post('/ban', {
preserveScroll: true,
onSuccess: () => form.reset(), // reset form if everything went OK
})
The success message, which you set with
return Redirect::route("speler", [$steam])->with("success", "Ban doorgevoerd!");
is usually taken care of by the Inertia middleware and made available as 'Shared data'. See this docs page on how to configure that. Shared data is rendered in $page.props variable. That is where you can find the Ban doorgevoerd! message. You can show these to the user as follows:
<div v-if="$page.props.flash.message" class="alert">
{{ $page.props.flash.message }}
</div>
Depending on your implementation, you would need to watch this property. See the FlashMessages component on the pingCRM demo app for an example implementation.

Creating a link using laravel routes and vue.js

On my laravel home page I have a vue component like this
<new-tutor area-id="{{ $area->slug }}" tutor-id="{{ $tutor->slug }}" route="{{ route('tutor.show', [$area, $tutor]) }}"></new-tutor>
it returns all new tutors in a given area in individual bootstrap cards, and uses this controller
public function index(Request $request, Area $area, Profile $profile, Tutor $tutor)
{
$newTutors = Tutor::with(['user', 'area'])->inArea($area)->latestfirst()->get();
return response()->json($newTutor, 200);
}
I would like to be able to click on the tutors name and be sent to that tutors page, but I can't seem to get the tutor slug to pass though properly, and I am not sure why.
In my vue component I set the link like
<a :href="route">{{newTutor.name}}</a>
and I have props set up like this
props: {
areaId: null,
tutorId: null,
route: { type: String, required: true }
},
the slug does come through in a dd on newTutors, and Tutor.
Also note, I am using the same web route
tutor.show
in other blade templates, so I am mostly confident that that is not where the issue is.
if you using laravel + vuejs,You need add #{{}}
<a :href="route">#{{newTutor.name}}</a>

Get wordpress posts in categories via Ajax uisng Semantic UI API and tabs

I am trying to create tabs using semantic UI tabs and get content via an ajax call. I looked into the documentation but could't figure out a way to get the content from my wordpress site.
I want to create tab titles with category name and load the posts of that category via ajax when user clicks the title. I don't know if this is possible with the semantic UI API,
Thanks
You can call the wordpress api to get categories and put the category name, id and slug in a javascript object.
http://v2.wp-api.org/reference/categories/
Then loop through the object and show titles.
Use the slug to call
wp-json/wp/v2/posts/?filter[category_name]=uncategorized to get posts from category
Well if you are using symantic ui as a separate instance (not wp theme) and want to get content from the wordpress site then you need a REST api and not ajax. You should follow #Gisha James advice.
But if you are using symantic ui in a wordpress theme, and you want content to be loaded from the same wordpress installation then its a bit tricker because you need to understand how wordpress handles ajax, which basically works on 'admin-ajax.php'.
Here is a very simple implimentation taken from another answer.
// Footer or spearate js file
<script>
$(".post-link").click(function(){
var post_id = $(this).attr("rel"); //this is the post id
$("#post-container").html("content loading");
$.ajax({
url: myapiurl.ajax_url,
type: 'post|get|put',
data: {
action: 'my_php_function_name',
post_id: post_id
},
success: function(data) {
// What I have to do...
},
fail: {
// What I have to do...
}
});
return false;
});
</script>
// Function.php
add_action( 'admin_enqueue_scripts', 'my_ajax_scripts' );
function my_ajax_scripts() {
wp_localize_script( 'ajaxRequestId', 'myapiurl', array( 'ajax_url' => admin_url( 'admin-ajax.php' ) ) );
}
function my_php_function_name() {
// What I have to do...
}

Redirect from method in Vue.js with Vue-router older than version 1.x.x

I'm not much of a frontend developer but I know enough javascript to do the minimum.
I'm trying to plug into a last piece of login however my vue components are:
"vue-resource": "^0.9.3",
"vue-router": "^0.7.13"
I'm not experienced enough to move up to v1 or v2 respectively.
I would like to achieve something similar to this.
However I'm not getting a successful redirect.
my app.js file:
var router = new VueRouter();
...
import Auth from './services/auth.js';
router.beforeEach(transition => {
if(transition.to.auth &&!Auth.authenticated)
{
transition.redirect('/login');
}
else
{
transition.next();
}
});
```
In my login.js file
```
methods: {
/**
* Login the user
*/
login(e) {
e.preventDefault();
this.form.startProcessing();
var vm = this;
this.$http.post('/api/authenticate',
{ email : this.form.email,
password : this.form.password
})
.then(function(response){
vm.form.finishProcessing();
localStorage.setItem('token', response.data.token);
vm.$dispatch('authenticateUser');
},
function(response) {
if(response.status == 401)
{
let error = {'password': ['Email/Password do not match']};
vm.form.setErrors(error);
}else{
vm.form.setErrors(response.data);
}
});
}
}
I tried to do as suggested:
vm.form.finishProcessing();
localStorage.setItem('token', response.data.token);
vm.$dispatch('authenticateUser');
vm.$route.router.go('/dashboard');
However all it did was append the url on top.
I see that the 3 previous events were successfully done but not the redirect.
it went from:
http://dev.homestead.app:8000/login#!/
to
http://dev.homestead.app:8000/login#!/dashboard
when I need the entire page to go to:
http://dev.homestead.app:8000/login/dashboard#1/
I think i have a missing concept in order to do the redirect correctly.
UPDATE
As per suggested i have added param: append => false but nothing happens.
what i did afterward was within app.js create a method called redirectLogin() with console.log() outputs - that worked. what i did further is i put vm.$route.router.go inside there and called the method via vm.$dispatch('redirectLogin'); and that also didn't work.
NOTE:
The HTML is being rendered in Laravel first. the route I originally had (and working) as login/dashboard and that route is available via normal Laravel route. the blade is being rendered via view template.
So far I've been trying to vue redirect over to login/dashboard (not working) perhaps I should somehow remove login/dashboard and use the route.map and assign login/dashboard?
I would rather keep the login/dashboard as a laravel route due to authentication and other manipulation.
For Vue 2
this.$router.push('/path')
As par the documentation, router.go appends the path in the current route, however in your case it is appending along with # in the router as well.
You can use param: append, to directly arrive at your desired destination, like following:
vm.$route.router.go({name: '/login/dashboard#1/', params: {append: false}})
Edited
If it is not happening, you can try $window.location method like following:
var url = "http://" + $window.location.host + "login/dashboard";
console..log(url);
$window.location.href = url;
I think their is a misunderstanding here of how vue-router works. It seems you are not wanting to load a new route with a corresponding component, rather you simply want to redirect to a new page then let that page load and in turn fire up a fresh instance of vue.
If the above is correct you don't need vue-router at all. Simply add the below when you need to load the page:
window.location.href = '/login/dashboard'
If you'd rather simulate a redirect to that page (no back button history) then:
window.location.replace('/login/dashboard')
EDIT
The above would be fired when you have finished all processing that the page must run to set the users state which the next page requires. This way the next page can grab it and should be able to tell the correct state of the user (logged in).
Therefore you'll want to fire the redirect when the Promise has resolved:
.then(function(response){
vm.form.finishProcessing()
// store the Auth token
localStorage.setItem('token', response.data.token)
// not sure whether this is required as this page, and in turn this instance of vue, is about to be redirected
vm.$dispatch('authenticateUser')
// redirect the user to their dashboard where I assume you'd run this.$dispatch('authenticateUser') again to get their state
window.location.replace('/login/dashboard')

Why creating a route with angular-fullstack creates a component?

Im using angular-fullstack newest version I think "generatorVersion": "3.7.5", and right now I created a route
yo angular-fullstack:controller products and it created the files:
products.controller.js
products.controller.spec.js
products.js
products.scss
and when I tried
yo angular-fullstack:controller product_new_view
inside the folder /client/app/products it created a new folder
/client/app/products/product_new_view
which I think is ok but the question is why the controller definition is not inside a component as in /client/app/products/products.controller.js
angular.module('meanshopApp')
.component('products', {
templateUrl: 'app/products/templates/products.html',
controller: ProductsComponent
})
})();
instead is just
angular.module('meanshopApp')
.controller('ProductNewViewCtrl', function ($scope) {
$scope.message = 'Hello';
});
does that mean that for every new view I need to create a route? cause I read https://docs.angularjs.org/guide/component and there it says
Components as route templates
Components are also useful as route templates (e.g. when using ngRoute). In a component-based application, every view is a component:
Im new to angular by the way

Resources