Returning value from ajax in vuejs - php

Im trying to pass an integer (id) to a function which calls an api. The api then checks if the id passed matches any data in the database and returns the name associated with the id. I'm using vue.js for this along side laravel. Below is my code.
<tr v-for="store in storeList" :key="store.id">
<td>{{ getNodeName(store.store_name) }}</td>
</tr>
getNodeName(nodeId)
{
axios.get('api/store/getNodeName/'+nodeId).then(function (response){
return response.data[0].name;
});
}
Now the question is how do I get the result to print inside the td tag. apparently return from ajax doesnt work and I tried pushing it all to an array and printing it again but it didnt work either.
thanks

Assuming your API works, the first thing you are doing wrong is that you are returning from the callback when the Promise is resolved and not from the getNodeName method.
One simple way to achieve what you want, is to loop through your storeList (assuming it's a prop) inside the mounted lifecycle hook (using arrow functions here)
...
<tr v-for="node in nodes" :key="node.id">
<td>{{ node.name }}</td>
</tr>
...
data() {
return {
nodes: []
};
},
mounted() {
this.storeList.forEach(store => this.getNodeName(store.store_name));
},
methods: {
getNodeName(nodeId) {
axios.get('api/store/getNodeName/' + nodeId)
.then(response => this.nodes.push({ id: nodeId, name: response.data[0].name }))
}
}
...
You probably also want to turn this into one API call if possible, since you are making storeList.length calls.

You can make a loop of storelist and get nodeId from there and then do the API calls.
<tr v-for="store in storeData" :key="store.id">
<td>{{store.name}} </td>
</tr>
data(){
return{
storeData : []
};
},
created(){
for(var i=0; i<this.storeList.length; i++){
axios.get('api/store/getNodeName/' + this.storeList[i].store_name)
.then(response => this.storeData.push({ id: this.storeList[i].store_name,
name: response.data[0].name
}))
}
}

Related

How to Pass an array from Laravel Blade to a Vue Component in Laravel 6/Vue 2.6.*

I am passing an object from my controller to my blade.php.file. From there I use object notation to get the variables from my object which leaves me with an array. I then am trying to pass that array of data from my blade.php file to my vue component. I want to pass the entire array not just one index of it. As of right now when I try to pass the array I get the error htmlspecialchars() expects parameter 1 to be string, array given which makes sense because I am passing an array (which is what I want). How do I successfully pass an array of data from laravel blade to VUE?
blade.php file
<div id="app">
<draggable
draggable-table="{{ $table->vars }}">
</draggable>
</div>
VUE component
<template>
</template>
<script>
export default {
props: ['draggableTable'],
};
</script>
EDIT:
As suggested to me I added a : and json_encode in my blade fole table like so:
:draggable-table="{{json_encode($table->vars)}}">
But when I check my VUE console my component no longer shows and only root is shown with none of the array data passed in. (See photo)
2ND EDIT:
I am trying to do this via axios now. I added this to my component within the <script> tags
data(){
return{
table: this.draggableTable
}
},
methods: {
getData(){
axios.get(this.endpoint, {
table: this.table,
}).then(res => {
console.log(res);
}).catch(err => {
console.log(err);
});
}
},
computed: {
endpoint(){
return window.location.protocol + "//" + window.location.host + '/users';
}
}
app.js
const app = new Vue({
el: '#app'
});
So now how to I pass the data from blade to VUE?
Thank you.
you have to add : in prop, live below code.
<div id="app">
<draggable
:draggable-table="{{ json_encode($table->vars) }}">
</draggable>
</div>
You can just send it as a JSON object and then parse it either in Vue or when accepting it as a prop.
<div id="app">
<draggable
:draggable-table=JSON.parse({{ json_encode($table) }})>
</draggable>
</div>
Why would you need to pass data from Blade to Vue if you are using an API call in Vue? Data is already available to you.

Laravel delete link for items within a foreach loop

I am attempting to delete an item within a foreach loop. In this loop, there are several images within $property. For each image ($propimg), I want to delete each image using it's id. However the link doesn't work. How do I get it to delete the individual image?
#foreach($property->images as $propimg)
<li>{{ $propimg->id }}<br/>{{ $propimg->image_url }}</li>
Delete
#endforeach
You need to perform an Ajax request, please try this:
$("[data-method='delete']").click(function(event) {
event.preventDefault();
$.ajax({
type: "DELETE",
url: $(this).prop("href")
}).always(function () {
location.reload();
});
});
If you get 500 HTTP error, due to CSRF token mismatch, please add this:
$.ajaxSetup({
headers: {
"X-XSRF-TOKEN": document.cookie.match('(^|; )XSRF-TOKEN=([^;]*)')[2]
}
});

How to work with a lot (thousands) of Eloquent records in Laravel 4

I need to get all data records from a clients table, there is more than 18000 records.
I use DataTables jQuery plugin to display data, so I do not want to use paginate Laravel method here.
I just want to retrieve data and pass to DataTable jQuery. This plugin does pagination.
This is my Controller code:
$data = Client::orderBy('created_at', 'desc')->get();
I got 500 error, because the result is too big.
I do not want to set higher memory limit, I want to use limitations or similar.
I tried this:
$data = Client::orderBy('created_at', 'desc')->take(10)->skip(1200)->get();
But it only gets 10 records and no more.
Any idea?
you can use Laravel Datatable package which is more effective and easy to use, here is my example that How I am doing it.
Note: I am using Yajra Datatable package for this, you all basic requirement will be cover in this.
My Controller method, where datatable Ajax request will come
public function getData()
{
$users = User::whereHas('roles',function($q){
$q->whereNotIn('roles.name',['user','memberstudent','educationmanager']);
})->select(array('users.id','users.firstname','users.lastname' ,'users.username','users.email',DB::raw("'roles'"), 'users.confirmed', 'users.created_at'));
return Datatables::of($users)
//->edit_column('created_at', '{{ $created_at->format("Y-m-d h:i:s") }}')
->edit_column('created_at', '{{ date("Y-m-d", strtotime($created_at))}}')
->edit_column('confirmed','#if($confirmed)
Yes
#else
No
#endif')
->add_column('roles','{{ implode(", ", User::find($id)->roles()->lists(\'name\')) }}')
->add_column('actions', '
#if(Auth::user()->hasRole("owner"))
<div class="btn-group">
<i class="fa fa-pencil"></i> {{{ Lang::get(\'button.edit\') }}}
<i class="fa fa-trash-o"></i> {{{ Lang::get(\'button.delete\') }}}
</div>
#elseif(Auth::user()->hasRole("superadmin") && User::find($id)->roles()->pluck(\'name\') != "owner")
<div class="btn-group">
<i class="fa fa-pencil"></i> {{{ Lang::get(\'button.edit\') }}}
<i class="fa fa-trash-o"></i> {{{ Lang::get(\'button.delete\') }}}
</div>
#endif
')
->remove_column('id')
->remove_column('rn') // rownum for oracle
->remove_column('created_at') // rownum for oracle
->make();
}
My view is
<table id="users" class="table table-striped table-hover table-bordered">
<thead>
<tr>
<th class="col-md-2">first name</th>
<th class="col-md-2">last name</th>
<th class="col-md-2">username</th>
<th class="col-md-2">email</th>
<th class="col-md-2">roles</th>
<th class="col-md-2">activated</th>
<th class="col-md-2">actions</th>
</tr>
</thead>
</table>
MY JS code is
<script type="text/javascript">
var oTable;
$(document).ready(function() {
oTable = $('#users').dataTable( {
"sDom": "<'row'<'col-md-6'l><'col-md-6'f>r><'row'<'col-md-6'i><'col-md-6'p>>t<'row'<'col-md-6'i><'col-md-6'p>>",
"aoColumnDefs": [
{ "bSearchable": true, "bSortable": false, "aTargets": [ 2,5 ] }
],
"sPaginationType": "bootstrap",
"oLanguage": {
"sLengthMenu": "_MENU_ records per page"
},
"bProcessing": true,
"bServerSide": true, //this means data will come from server, ajax based
"sAjaxSource": "{{ URL::to('admin/users/data') }}", // get data from this URL
"fnDrawCallback": function ( oSettings ) {
$(".iframe").colorbox({iframe:true, width:"80%", height:"80%"});
}
});
});
</script>
You really, really need to use server-side pagination in this case.
The problem with relying on client-side pagination (i.e., the plugin's pagination feature) is that the response from your API containing all 18,000 records will be humongous, and your users will not only have to wait for the request to complete (which literally could take minutes for this much data), but depending on how the plugin works they may also have to wait while it renders the DOM for all these records.
It looks like Datatables supports server-side pagination. Why not give that a try?
I have adopted another solution, using paginate method from laravel and forget DataTables plugin, DataTables is a great plugin!, but in my case, to use this plugin, would have to implement an ajax script to get data.
Currently I have the system implemented to work with routes, controllers, views with Teepluss themes and a search tool.
I thought there was a simpler way to implement this plugin with Laravel using MVC pattern.
With this lines I have what I need:
My controller
public function index()
{
$data = Client::orderBy('created_at', 'desc')->paginate(50);
$theme = Theme::uses('mytheme');
$view = array(
'name' => 'Teepluss',
'data' => $data,
);
return $theme->scope('clients.index', $view)->render();
}
My view
//-- Table head here
#foreach($data->getCollection()->all() as $value)
//-- Table and data here
#endforeach
//-- Pagination links
{{ $data->appends(Request::except('page'))->links() }}
No 500 error, get all data, pagination working fine. Of course, I am giving up other features of DataTables plugin for the moment...
Anyway thank you very much!

Symfony2 - Issue getting correct id to show/{id}

I have a view page which is passed all my active alerts. On each displayed row, I have a show button so you can see the individual alert
{% for alert in alerts %}
<tr>
<td>{{ alert[0].id }}</td>
<td>{{ alert[0].alertStatus }}</td>
<td>
<input type="button" value="Show" data-url="{{ path('NickAlertBundle_show', {id: alert[0].id}) }}" onclick="show_alert( {{ alert[0].id }} )" id="show"/>
</td>
</tr>
{% endfor %}
So when the button is clicked, the javascript function show_alert is called.
function show_alert(id){
alert(id);
$.ajax({
type: "POST",
url: $("#show").attr('data-url'),
data: {id: id},
success: function(data) {
if(data){
}else{
alert("Unknown Error!");
}
},
error:function(){
alert(id);
}
});
}
Now I do an alert at the top of that function, and that alert always displays the correct id. I think the problem is with the url part of the ajax call. It calls the data-url which should be correct. This is what it should be calling
NickAlertBundle_show:
pattern: /show-alert/{id}
defaults: { _controller: NickAlertBundle:Alert:show }
requirements:
_method: GET|POST
id: \d+
So this should then call the controller action
public function showAction(Request $request, $id)
{
var_dump($id);
if($request->isXmlHttpRequest())
{
$id = (int)$request->request->get('id');
}
return new JsonResponse('test');
}
At this point though, the var_dump in this action always outputs the id of the last added alert, and not the selected alert. And when I display the alert, it always displays the latest added alert.
So what is causing it to get the latest alert id instead of the selected id? As I say, it initially gets the correct id, but at some point this changes.
Thanks
You shouldn't declare duplicated ids, like id="show" in your template, better use class or declare your ids like id="show_1 ... n"

Populate table in Laravel with ajax?

I have a Laravel application where I create a page layout, adding a table to it as a "content" variable (pretty much all from tutorials I found). Here's the controller action:
public function getMain() {
$js_config = Category::all();
$resources = Resource::all()->take(100);
$this->layout->content = View::make('categories.show')->with('js_config', $js_config)->with('resources', $resources);
}
This uses the main layout template and inserts this table using the content variable:
<table class="table table-striped table-bordered">
<thead>
<tr>
<td>ID</td>
<td>Name</td>
</tr>
</thead>
<tbody>
#foreach($resources as $key => $value)
<tr>
<td>{{ $value->id }}</td>
<td>{{ $value->title }}</td>
</tr>
#endforeach
</tbody>
</table>
But then comes the problem: I have a jstree where the user can select nodes, triggering a jQuery method:
$('#jstree2').on("changed.jstree", function (e, data) {
console.log(data.selected);
$.get("filter", { category: data.selected })
.done(function (resultdata) {
//Test only, this returns the data wanted in json, which I stringify just to display in test
alert("Data Loaded: " + JSON.stringify(resultdata));
});
});
The jQuery calls this action method in the controller:
public function getFilter()
{
$input = Input::get('category.0');
$categories = Category::find($input);
//category is the name from the model below
return Response::json(array(
'error' => false,
'category' => $categories->toArray()),
200
);
}
(The reason there's an array as input is I eventually want to be able to allow picking multiple nodes in the tree)
This action gets the data from the DB correctly and returns it as json. The callback in the jQuery above then alerts this at the moment, just as a test.
But what I really want to do, of course, is to repopulate the table. Now, as you can see I have used Bootstrap to create a pretty table and all, and I just want to be able to let the user repopulate it at will, without refreshing the page.
But I don't know how to do that, except by painstakingly recreate this table in some sort of string return value, but that doesn't seem like a good idea.
I'm hoping there's some way of passing the return value back to the view and have it reload the values in the table, utilizing the same "sub view" that I loaded in the php variable "content" as described above?
Any help greatly appreciated!
EDIT:
As requested, here's a sample of the json (taken from the browser console output, and it's actually not the categories table, but the same format):
[{"id":"1","title":"Transportation AC 4494","created_by":"4","modified_by":null},{"id":"2","title":"Safety First AC 4294","created_by":"3","modified_by":null},{"id":"3","title":"Warranty AC 34066","created_by":"4","modified_by":null}]
EDIT 2 (Just realized there was some crap from the controller in the previous edit of the json, so I changed it to a cleaner sample now)
EDIT 3:
I have made this work by creating the table rows in jQuery:
var trHTML = '';
$.each(resultdata, function (i, item) {
trHTML += '<tr><td>' + item.id + '</td><td>' + item.title + '</tr>';
});
$('#ajaxtable').html(trHTML);
But mainly I'm hoping this might explain my question better: this is not what I wanted to do. What I would have wanted was to just create a partial view and then load that ready-made view with the jquery:
A partial view like this:
<table class="table table-striped table-bordered" id="resultstable">
<thead>
<tr>
<td>ID</td>
<td>Name</td>
</tr>
</thead>
<tbody id="ajaxtable">
#foreach($resources as $key => $value)
<tr>
<td>{{ $value->id }}</td>
<td>{{ $value->title }}</td>
</tr>
#endforeach
</tbody>
</table>
I tested this by creating and calling a new function in the controller from the jquery code:
public function getTable()
{
$resources = Resource::all()->take(5);
return View::make('categories.results')->with('resources', $resources);
}
But it doesn't work. Although it does indeed give me the html of that view, it is unprocessed. I.e, the foreach loop is not resolved, but still there as code in the table. See the image:
So how can I load this view with the jquery code? It feels to me that even if the jquery creation of table rows works, doing the view in php and then just loading it with jquery should be the more correct way of doing it...?
Have you looked into the Datatables jQuery plugin? There is actually a nice package for Laravel that helps integrate Laravel and Datatables. The Laravel package generates the json and you can use Datables+AJAX to repopulate the data. Might be working checking out...
https://github.com/Chumper/datatable
http://datatables.net/
Otherwise, you'll just need to use AJAX to repopulate the table.
As Sirago answered, using jQuery Datatables is a good option to load data into tables in ajax manner.
In addition to what Sirago suggested, here is another great Laravel 4 package which is dedicated to generate JSON data from server side.
https://github.com/bllim/laravel4-datatables-package
But apart from server side configuration(modifying files like composer.json, config/app.php etc.), you need to code in Javascript, utilizing Datatables as well.

Categories