How I get model attribute in Vue? - spring

How can i get Model Attribute in Vue?
This is My controller in backend(Spring).
#CrossOrigin(origins = "http://localhost:8080")
#PutMapping("/board/postlist")
public String boardList(Model model){
model.addAttribute("posts", postService.findAllDesc());
model.addAttribute("attrTest", "WHATTHOE");
return "IndexController.update() working";
}
postsis a List.First, I guess my list or sth was wrong. So i add another String attribute attrTest but still in problem...
And this is my vue template.
<b-textarea placeholder="${attrTest}"></b-textarea>
And this is part of my vue script.
<script>
export default {
name: "postList",
data: ()=>({
content:'',
author:'',
})
}
</script>
Screen just display ${attrTest}, in text. It doesn't seem recognize variable.
I been searching many solutions but it doesn't work for me. I tried ${} like jquery but also failed. Maybe my project doesn't have jquery... i can't found jquery in my pakage.json too.
In mustache, i just write {{#posts}} for get model atrribution. Also use Axios result succesfuly but is it impossible to get model attribute with Vue solution? like $attr or sth.
Is it necessary to install jquery?
now I don't no where to start. I tried get posts list all day long. I really need help.

If you're using Thymeleaf as view resolver, try th:placeholder

Related

Vue2 + laravel6 - Component implementation

I just started using Vue2 with Laravel6 and got stuck when trying to understand how to use component method.
As I am totally new for Vue, I am using the official tutorial of Vue as a reference. What I learned from here(https://v2.vuejs.org/v2/guide/components.html) about Vue component instantiation is we give options to a component.(e.g. we give 'template:' options for HTML part.)
When I look at laravel6 codes of resouces/js/app.js, it looks something like this:
Vue.component('example-component', require('./components/ExampleComponent.vue').default);
I looked at js/components/ExampleComponent.vue expecting to see some options declared there. However, there's no option in the ExampleComponent.vue file. Instead, I see <template></template> tag. Apparently, the <template></template> tag seems to work as 'template:' option.
I have two questions regarding above:
Does <template></template> tag have the same meaning as 'template:' option?
If question 1 is yes, are other options also replacable with corresponding tags? (e.g. Can I use <props></props> tag for 'props:' option? or <data></data> tag for 'data:' option?
Thanks in advance!
In Vue world, there are two popular types of defining a component
First Type
in this type, you add all of your HTML inside the template property
and the props add as attribute inside the component object to
Vue.component('button-counter', {
data: function () {
return {
count: 0
}
},
template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>'
})
Second Type
in this type you add your component logic in a separate file ends with .vue
for example in laravel there is an ExampleComponent.vue file you will find on
it just template tag just as a wrapper for your component content and your logic you can write it as it mentions below.
<template>
// some content here
</template>
<script>
export default {
props: [],
methods: {
},
data(){
return {
}
}
}
</script>
Finally
there is no tag called props or data
for more info read this article

Best practice to pass data from Laravel to Vue component

This is my blade code
<div id="app">
<Testcomponent bam-wam="ham" />
</div>
This is my VueJS Component code
<script>
export default {
name: "ExampleComponent",
props: [
'bamWam'
],
data () {
return {
};
},
created() {
console.log(this.bamWam);
}
}
</script>
Question is
This code runs good but I am asking what is better using Axios and Vuex to fetch data from my Laravel app or simply Pass data throw props like I did in this code?
Pass data through props is the best way.
<my-component my-data="yourData"></my-component>
If you want to use laravel variable for data from blade then,
<my-component my-data="'{{ $data->id }}'"></my-component>
<my-component :my-data="'{!! json_encode($data) !!}'"></my-component>
Avoid api call as much as possible. It will reduce the total number of request to server and expose fewer number of api endpoint.
If the data is available to the view where the component is added. Then the best way to pass php arrays from laravel to a vue component is to utilize json encoding like so:
<my-component :needed-data='#json($laravelCollection)'></my-component>
This will make you will be easily to perform actions to the php array in the Vue controller as if it was a JS object. Keep in mind that you have to use single quotes for #json.
For simple strings you can just directly pass it as props without the encoding.
This approach is better than creating a new API specifically for this component.
This was the only way that works for me:
<my-component :data="{{ $collection }}"></my-component>
JSON parsed solutions prints data in HTML.

call to ReactJS component in Laravel blade templates

I use Laravel 5.4 and React 15.5.4, code is writing in ES6.
I'd like replace Vue and use React and I did it. But I often will use small components for example 2 in different places of blade template. I don't want use one app component.
I'd like use something like:
<span class="react">
<TestComponent property={true} />
</span>
I can't do it automatically. Now I use
<span data-component="TestComponent" data-props="{property:true}" />
and in app.js
_.each(document.querySelectorAll('[data-react]'), element => {
let props ={};
Array.prototype.slice.call(element.attributes)
.forEach(item => {
props[item.name] = item.value;
if(item.name !== 'data-react'){
element.removeAttribute(item.name);
}
});
ReactDOM.render(React.createElement(reactComponents[element.getAttribute('data-react')],props),element);
});
It works but I need to use add all properties to one react component property and then use for example this.props.out.propery
I also would like set normal component tag in my blade component
I've try to use in app.js
_.each(document.querySelectorAll('.react'), item => {
ReactDOM.render(item.children,item);
});
Someone have any idea to solve this problem?
EDIT
I changed my solution to:
<span data-react="LoginForm" input="{{json(request()->old())}}" error="{{session('error')}}" errors="{{json($errors->getMessages())}}" />
or
<LoginForm data-react="LoginForm" input="{{json(request()->old())}}" error="{{session('error')}}" errors="{{json($errors->getMessages())}}" />
in blade and in resources/assets/js/app.js
var reactComponents = {
LoginForm: require('./components/login').default,
};
_.each(document.querySelectorAll('[data-react]'), element => {
let props ={};
Array.prototype.slice.call(element.attributes)
.forEach(item => {
props[item.name] = item.value;
});
ReactDOM.render(React.createElement(reactComponents[element.getAttribute('data-react')],props),element);
});
It works fine. This is not super clear solution but I have impression that the reasonable.
I can set components name in html code and add props almost same like in JSX.
As far as I know, you can not mix JSX components directly with Blade templates. The only server side rendering available today for React is NodeJS.
What you could do to improve your architecture is add specific HTML tags with certain ids and render the react components in them. So inside Blade you could do something like:
<div id="componentA"></div>
This will act as a place holder in your Blade template for that react component. Then you render your componentA from your app.js like this:
React.render(<ComponentA prop1='valueX'/>, document.getElementById("componentA"))
Remember that in this case the world of react and world of Blade run at different times.
You could use document.getElementsByTagName('LoginForm') getting all the instances and later iterate its attributes. It's clear code but not generic, because it will work just for LoginForm components.
If you want to render any tag name, then maybe it's better to use some attribute as you used with data-react.
getElementsByTagName isn't super supported by old browsers so maybe could a good idea to use jQuery as fallback $('LoginForm')

JavaScript code in view issue in Laravel

I put JavaScript code in a view file name product/js.blade.php, and include it in another view like
{{ HTML::script('product.js') }}
I did it because I want to do something in JavaScript with Laravel function, for example
var $path = '{{ URL::action("CartController#postAjax") }}';
Actually everything is work, but browser throw a warning message, I want to ask how to fix it if possible.
Resource interpreted as Script but transferred with MIME type text/html
Firstly, putting your Javascript code in a Blade view is risky. Javascript might contain strings by accident that are also Blade syntax and you definitely don't want that to be interpreted.
Secondly, this is also the reason for the browser warning message you get:
Laravel thinks your Javascript is a normal webpage, because you've put it into a Blade view, and therefore it's sent with this header...
Content-Type: text/html
If you name your file product.js and instead of putting it in your view folder you drop it into your javascript asset folder, it will have the correct header:
Content-Type: application/javascript
.. and the warning message will be gone.
EDIT:
If you want to pass values to Javascript from Laravel, use this approach:
Insert this into your view:
<script type="text/javascript">
var myPath = '{{ URL::action("CartController#postAjax") }}';
</script>
And then use the variable in your external script.
Just make sure that CartController#postAjax returns the content type of javascript and you should be good to go. Something like this:
#CartController.php
protected function postAjax() {
....
$contents = a whole bunch of javascript code;
$response = Response::make($contents, '200');
$response->header('Content-Type', 'application/javascript');
....
}
I'm not sure if this is what you're asking for, but here is a way to map ajax requests to laravel controller methods pretty easily, without having to mix up your scripts, which is usually not the best way to do things.
I use these kinds of calls to load views via ajax into a dashboard app.The code looks something like this.
AJAX REQUEST (using jquery, but anything you use to send ajax will work)
$.ajax({
//send post ajax request to laravel
type:'post',
//no need for a full URL. Also note that /ajax/ can be /anything/.
url: '/ajax/get-contact-form',
//let's send some data over too.
data: ajaxdata,
//our laravel view is going to come in as html
dataType:'html'
}).done(function(data){
//clear out any html where the form is going to appear, then append the new view.
$('.dashboard-right').empty().append(data);
});
LARAVEL ROUTES.PHP
Route::post('/ajax/get-contact-form', 'YourController#method_you_want');
CONTROLLER
public function method_you_want(){
if (Request::ajax())
{
$data = Input::get('ajaxdata');
return View::make('forms.contact')->with('data', $data);
}
I hope this helps you... This controller method just calls a view, but you can use the same method to access any controller function you might need.
This method returns no errors, and is generally much less risky than putting JS in your views, which are really meant more for page layouts and not any heavy scripting / calculation.
public function getWebServices() {
$content = View::make("_javascript.webService", $data);
return (new Response($content, 200))->header('Content-Type', "text/javascript");
}
return the above in a method of your controller
and write your javascript code in your webService view inside _javascript folder.
Instead of loading get datas via ajax, I create js blade with that specific data and base64_encode it, then in my js code, I decode and use it.

Sammy intercepts a POST that is not one of the added routes

I have an application that uses Sammy for some simple client-side routing.
One of the pages has a "Download Pdf" button, which needs to do a POST to get and download a pdf document (not very resty, I know, but it has to be a POST due to the large amount of data I'm submitting). It does this using the old trick of dynamically creating, populating, and submitting a <form> element.
Everything works fine, except for I can see in the console an error from sammy that my route was not found. Note that this is not a route, or even a verb that Sammy should be handling.
Here is my reduced test case
Sammy(function initializeClientRouting(app) {
app.get('#/', show('#default'));
app.get('#/test', show('#test'));
function show(selector) { return function() {
$('section').slideUp();
$(selector).slideDown();
}; }
}).run('#/');
$('button').click(function() {
var form = $("<form method=post action: 'http://www.google.com'>").hide();
$('<textarea name=q>').text("search text").appendTo(form);
form.appendTo('body').submit().remove();
});
Does anyone know how to prevent this error? Is this a bug in Sammy?
It's a combination of sammy & JQuery behaviour (bug?). When generated dynamically the way you put it, the form tag is being rendered as
<form www.google.com'="" 'http:="" action:="" method="post">
This will try to POST to the current page which probably is something like
http://blah/# or http://blah/#/test
For some reason, Sammy will be triggered because of the hashtag, not finding a POST configured and log an error.
Fiddling with your example, what worked for me was:
var form = $("<form>");
form.attr('method', 'post');
form.attr('action', 'http://www.google.com');
$('<textarea name=q>').text("search text").appendTo(form);
form.appendTo('body').submit().remove();
This seemed to generate the proper HTML and remove the Sammy error.

Resources