Pass data from blade file directly to Vue instance - javascript

I am working on a Vue application that's living in a Laravel project. I bind my vue instance to an id that's placed in a blade file.
What I would like to do is to pass the logged user to my Vue instance from Laravel/blade. Is there a way to do this? I know you can pass data through props but this here is just a regular div with an id of #root that's binding the Vue instance. I know how to get the logged user, but I am specific looking for an way to directly pass the data from blade to my vue instance.
app.js
// Require the deps from laravel (jQuery, axios, Bootstrap)
require('./bootstrap');
// Import vue deps
import Vue from 'vue';
import VueRouter from 'vue-router';
Vue.use(VueRouter)
// Import the router & routes
import router from './routes'
// Init a new vue instance
const root = new Vue({
el: '#root',
data: {
User: name here..
},
router
});
Blade
#extends('layouts.app')
#section('content')
<!-- pass user below -->
<div id="root"></div>
#endsection

In your blade file, pass the logged user information to a javascript global variable. Let's say you just want the user id and name:
<script>
window.auth_user = {!! json_encode([
'id' => auth()->user()->id,
'name' => auth()->user()->name
]) !!};
</script>
Then in your javascript, you can access the auth_user global variable.
For example, to log the user name:
console.log(auth_user.name)
or
console.log(window.auth_user.name)

You have few options (I think I not list all) e.g:
You can pass data by converting them to json and write as HTML element or attribute and then read it from vue using e.g. document.querySelector(...) - more info here: Best way to store JSON in an HTML attribute?
You can change a littlebit architecture and create separate (Restful) API which your vue components will be use via ajax to read data (e.g. you can create GET api/v1/currentUser do read current logged user)
Completly change your architecture - to "microservices" - so in laravel only create Restful API, and creatte SEPEARATE project with vue (and NO laravel) user interface which use that API (it is modern approach to separation backend from frontend). You will face CORS problem in this approach but its no so hard (only at first time).

You might want to take a look at the PHP-Vars-To-Js-Transformer
package. You can use it either in your controller or in a #php directive.
Probably not a good practice with VueJS though.

Related

Vue: Use Vuex store outside of component without Import Statements

In Vue 2/3, and in an ES6 environment when I want to access a Vuex store in an external JS file (outside of the component), I would normally use something like this:
// example.js
import { store } from '../store/index';
console.log(store.state.currentUser);
This works great, however, in my current environment (Rails 5 without webpack), we can't use import statements at all.
Question: Is there any way, in regular ES5 JavaScript, to access Vuex stores outside of components?
It's worth noting that I've got a successful setup of Vuex going on our frontend, we just can't access it outside of our defined Vue components.
In my Rails setup, I have this:
// app/assets/javascripts/lib/vuex/store.js
const store = new Vuex.Store({
modules: {
activity: activityStore,
}
});
// application.js
//= require vue/dist/vue.min
//= require vuex/dist/vuex.min.js
$(document).ready(function () {
Vue.use(Vuex);
});
In this instance, store is just a global javascript object. Use it the same as you would any other JS object.
As long as you're inside a JS file that is properly compiled, and your base Vue is installed properly, you can just do store.state.activity.activities, or if you have mutations, store.commit('myMutation', 'Hello test').
My specific example was a huge function calling a webhook. The webhook can take a while, and I want to send messages to the user as I get new messages.
Example:
// webhook.js
async webhookFunction() {
// new message recieved
store.commit('newActivity', 'Your object has been updated');
}

How to properly store non-reactive and static data in an vue?

Greetings to the community! This is my first question on the StackOverflow.
I use vue.js-v2 and webpack. I need to have immutable data available for child components. The components are loaded via the vue-router. Different pages need the same data.
I import data from a JSON file and integrate it into vue with a "main.js":
//main.js
import Vue from 'vue'
import ...
import myData from './path/file.json' // [{},{},{}...]
Vue.prototype.$storage = myData
new Vue({ router, .....
Then I use in different components something like:
//pageX.vue
...
this.componentVar = this.$storage.filter((x) => x.name === 'needName')
And somehow it works. I worry if I'm doing the right thing. I am afraid of duplicating data in components or something like that, because my knowledge of javascript is deplorable :(
You have to use Vuex to store that data.. wheater immutable or not a state of an app has to a single absolute source of truth and no alternative compared to vuex can help you in this case

How to make a component with a runtime template in Angular?

I need to code a page that will have its template defined in the server. The page makes an HTTP GET to the server and get a string that will be the template.
I'm trying to follow an example I found here: runtime-content.component.ts
However, in this template I'm going to have references to other components, such as <app-hello></app-hello> and when I try to render that I get that 'app-hello' is not a known element.
How can I tell this component to use a certain module or recognize certain components?
You just have to include the component references here (declarations):
#NgModule({ imports: [CommonModule, RouterModule], declarations: [decoratedCmp, ...declarations] })
class RuntimeComponentModule {}
And to send data add on compileTemplate
(this.componentRef.instance as any).data = this.data;
So your wrapper will have data available to be used on your template.
And on your dynamic template you can use data to send info to other components:
<app-something [content]="data?.content"></app-something>

Accessing $route.params in VueJS

Looking through this documentation:
https://router.vuejs.org/en/essentials/navigation.html
It looks like you can bind the <router-link :to="variableName">Link Text</routerlink> Which is pretty nifty; however, I've had some trouble trying to access route parameters inside of a component I'm trying to build.
So I use this:
<router-link :to="permalink">Title of thing</router-link>
To then direct the router view to pull the forum thread. Using this in the router:
import ForumThread from './views/groupTitle/forumThreadSingle';
// Other routes...
let routes = [
{
path: '/groupTitle/th/:id',
component: ForumThread,
}
];
I can see in the forumthread component that $route.params.id is being passed too it; however, when I try to access it like this:
console.log('The id is: ' + $route.params.id);
It's unable to find the params portion of the object.
VueJS is pretty new to me as well as JavaScript itself. All the examples I've seen show the templates being inline with the router file which is something I am trying to prevent to help keep my code readable and clean.
What adjustments can I make so that I can pass properties to the template file?
Thanks!
If you're using the Vue Loader setup (which has <template></template> tags in the files), you need to use this to reference the $router, if you're doing so within the <script></script> part of the file.
console.log('The id is: ' + this.$route.params.id);
For and one wanting to get params in vue 3 with composition API for vue-router 4.x, it can be achieved using useRoute.
import {useRoute} from "vue-router";
setup(){
const route = useRoute();
const id = route.params.id;
}

How can I access angular-redux store from child module?

In my angular app I use angular-redux for application state management. In my main module I defined my redux store. Like this:
export class MainModule {
constructor(private ngRedux: NgRedux<MainAppState>,
private devTools: DevToolsExtension) {
let enhancers = [];
if (environment.production === false && devTools.isEnabled()) {
enhancers = [...enhancers, devTools.enhancer()];
}
this.ngRedux.configureStore(
reducer,
{} as MainAppState,
[],
enhancers);
}
}
I created new child module, which contains some components. These components should access to application state. In one of these components I access via #select to store, but this doesn't work. Here is how I access to store:
export function getLanguage(state: LanguageState) { return state.userLanguage; }
And this code I have in my ChildComponent class:
export class ChildComponent implements OnInit {
#select(getLanguage) savedUserLanguage$: Observable<LanguageState>;
// more code
}
How can I access to application state store from child modules? What should I import in child module? Will It be better to create own module only for redux store handling? Maybe I forgot something?
I use Angular v4 and #angular-redux/store v6.
I'd recommend creating a separate module that just contains your store, e.g. StoreModule. You can then import your StoreModule into all your child modules and access your store from there.
This is the way they go in the official example app:
StoreModule: https://github.com/angular-redux/example-app/blob/master/src/app/store/module.ts
Child Module: https://github.com/angular-redux/example-app/blob/master/src/app/elephants/module.ts
Component in child module: https://github.com/angular-redux/example-app/blob/master/src/app/elephants/page.ts
I was thinking about refactoring some ugly old JavaScript code that uses prototypal inheritance into an Angular 7+ project. I was asking myself pretty much the same question. Inspired by my udemy Angular course, I tried an experiment with a ngrx store and lazy loaded modules.
(Keep in mind that ngrx is SIMILAR to #angular-redux, but it's NOT the same thing. See https://ngrx.io/docs for details.)
Here it is.
I create the store in the main module with StoreModule.forRoot and in each lazy loaded module, I create a reference to the store with StoreModule.forFeature.
(See https://ngrx.io/api/store/StoreModule for details.)
When I dispatch actions on the store with the lazy loaded components, those actions (and corresponding reducers) seem to change the value to which the main app component subscribes.
Also, when I dispatch actions on the store with the main app component, those actions (and corresponding reducers) seem to change the value to which the lazy loaded components subscribe.
Also, it's hard to explain what I did in a simple 200-500 character block so I had to use a github project.

Categories

Resources