i am fetching data, that i want to output from mysql with laravel query builder and converting it to JSON format, as w3Schools suggested
W3schools SQL link
And afterwards printing fetched mysql data with AngularJS help, but it doesn't seem to do anything at all and it shows me a blank page.
Laravel route
Route::get('/' , [
'as' => 'homepage',
'uses' => 'indexController#main'
]);
IndexController
class IndexController extends Controller
{
public function main(){
$data = json_encode(array('user_posts' =>\DB::table('posts')
->orderBy('added_on', 'desc')
->get()));
return view('index', ['posts' => $data]);
}
}
index.php view with AngularJS controller
<head>
<!--Angulare -->
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular-route.js"></script>
<!--Applicazione -->
<script src="js/app.js"></script>
<script src="js/controller/PoolController.js"></script>
<script src="js/service/poolService.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
</head>
<body>
<div ng-app="myApp" ng-controller="customersCtrl">
<table>
<tr ng-repeat="x in names">
<td>{{ x.username }}</td>
<td>{{ x.age }}</td>
</tr>
</table>
</div>
### Angular Module and controller ###
<script>
var app = angular.module('myApp', []);
app.controller('customersCtrl', function($scope, $http) {
$http.get("/")
.then(function (response) {$scope.names = response.data.user_posts;
});
});
</script>
</body>
Json output how it looks like:
{"user_posts":[{"id":1,"username":"Moly","age":22,"added_on":"2017-01-05 08:51:18"},
{"id":2,"username":"katja","age":22,"added_on":"2017-01-05 08:51:18"},
{"id":3,"username":"rumanova","age":22,"added_on":"2017-01-05 08:51:18"}]}
I've tried so far in AngularJS controller:
changing:
$http.get("/")
With
$http.get("homepage")
Also tried changing
response.data.user_posts
with
response.data.posts
Basically i'm kinda lost and can't seem to understand, what i am doing wrong.
Thanks in advance
You are always returning a rendered view which will never be a valid JSON response. Instead, check if it's an ajax request. Also, Laravel provides collection()'s which should be used in favor of raw arrays or json encoding where possible to provide stack cohesion. Try this:
if ($request->ajax()) {
return response()->json(collect(['user_posts' =>\DB::table('posts')
->orderBy('added_on', 'desc')
]));
}
return view('index);
Also, make sure you're injecting the $request into your controller's method:
public function main(Request $request) {
Furthermore, Angular doesn't have any idea about Laravel's routes, but that's okay. If you're using scripts directly inside of the view file, you still have access to Laravel's helpers, you can make your endpoint request:
$http.get('{{route('homepage')}}')
Otherwise, if your Angular is in a script, just do:
$http.get('/');
And you will access it within your HTTP request callback with response.user_posts.
You can use $routeProvider instead of $html like this:
app.config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/homepage', {
templateUrl: '/homepage.html',
controller: 'customersCtrl'
});
}]);
Related
I am trying to send variable with data from a function to laravel front page view and i get Undefined variable: data (View: C:\xampp\htdocs\laravelproject\resources\views\process-url.blade.php).
This is my code and web.php routes.
web.php
Route::get('/', [welcomechecker::class, 'getfrontpage']);
Route::post('process-url', [welcomechecker::class, 'saveformdata']);
welcomechecker.php controller
class welcomechecker extends Controller
{
function getfrontpage(){
return view('welcome');
}
function saveformdata(Request $request){
$client = new Client();
$data = [];
$url = $request->url; //getting value from ajax $url = $request->url;
$wp = $url.'/'.'wp-admin';
$website = $client->request('GET', $url);
$html = $website->html();
//Check if cms is wordpress
$cms = '';
if($this->isWordPress($wp, $html) == 'WordPress'){
$cms = 'WordPress';
$data['cms'] = 'WordPress';
}
return view('process-url', compact('data'));
}
view blade: process-url.blade.php
#foreach($data as $student)
{{$student->cms}}
#endforeach
front page view blade: welcome.blade.php
<div class="display-content alert-success" >
#include('process-url')
</div>
application.js having ajax code
jQuery(document).ready(function(){
$(document).ajaxStart(function(){
$("#wait").css("display", "block");
});
$(document).ajaxComplete(function(){
$("#wait").css("display", "none");
});
jQuery('#ajaxsubmit').click(function(e){
e.preventDefault();
jQuery('.alert').show();
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content')
}
});
jQuery.ajax({
url: 'process-url',
type: 'POST',
data: {
url: jQuery('#enter_url').val()
},
success: function(result){
console.log(result);
jQuery('.display-content').html(result.success).fadeIn(700);
// jQuery('.display- content').html(result.success).fadeIn(700).fadeOut(5000);
}});
});
});
Someone please help me to identify what i am doing wrong. I am trying to submit the variable data to the process-url blade view which is routed to the saveformdata() on the web.php. The error occurs in process-url.blade.php at the data variable. The saveformdata function has a whole lot of code than what i actually put here the whole idea is that it returns an array of data from a scraping tool which i want to display on a table on process-url blade
Of course you will get Undefined Variable error when you are trying to include a blade file that is waiting for an array $data which is only passed to the view when you hit the route process-url. Also it is really, really bad practice to return a view after a POST request. Anyways, to solve your error (because that's what you actually want) you can do the following:
Pass the $data to the welcome page view and remove it from the process-url view
function getfrontpage(){
return view('welcome', [
'data' => ['Balloon Fight', 'Donkey Kong', 'Excitebike']
]);
}
function saveformdata(){
return view('process-url');
}
Pass the $data array from the welcome view to the process-url view through #include
<div class="display-content alert-success" >
#include('process-url', ['data' => $data])
</div>
Your error now disappeared. Your code still makes no sense, but this is what you wanted.
In the first URL you show a welcome blade file and it includes process-url blade without data variable
you should pass data variable in getfrontpage function like saveformdata
and the include directive pass variable to child blade
function getfrontpage(){
$data = ['Balloon Fight', 'Donkey Kong', 'Excitebike'];
return view('welcome', compact('data'));
}
and data variable array type that student will show every element in the array
#foreach($data as $student)
{{$student}}
#endforeach
I need to make a category filter for my blog posts. I was toying around with Vue a bit. But since I have not learned Vue, I was recommended to just use Axios. I am completely lost. How does it work? I cannot even log a result from here? I did get it to work with an example in the App.JS from a SO question, trying to find that again. But thats Vue? I am not sure what to do anymore ? This is my example the /axios refers to a controller I show the controller first then the blade :
class AxiosController extends Controller
{
public function index()
{
$articles = Article::all();
//$categories = Category::all();
return response()->json($articles);
}
}
The blade ( I had it without the axios.create and all kinds of try outs I did) I also did it without the #once and the #push I just read this in the Laravel documentation.
#once
#push('scripts')
<script src="https://unpkg.com/axios/dist/axios.min.js">
const instance = axios.create({
baseURL: 'http://localhost:8000/axios',
timeout: 1000,
headers: {'X-Custom-Header': 'foobar'}
});
const axios = require('axios');
axios.get('http://localhost:8000/axios')
.then(function (response) {
// handle success
console.log(response);
})
</script>
#endpush
#endonce
I want to make a feature for my web app in laravel(i'm new at it) that every Post/Comment/Theme(in my case) the user has the ability to upVote and downVote. Now i am woking with upVote, but it is not working whatsoever.
In the view (welcome.blade.php)
I have:
<img class="media-object" style="height:40px; width:40px;" src="images/upVote.svg" alt="...">
Where $Theme->name is the one that the user wants to upVote/like(whatsoever).
The route:
Route::put('/', [
'uses'=>'Vote#VotePlus',
'as' =>'Voteplus' //Name of route
]);
And the controller:
<?php
namespace App\Http\Controllers;
use App\NewTheme;
use DB;
class Vote extends Controller {
public function VotePlus($name){
DB::table('New_Themes')
->where('name', $name)
->increment('upVotes', 1);
$Themes = NewTheme::paginate(5);
return redirect()->route('welcome', ['Themes'=>$Themes]);
}
};
I am trying everything, but it isn't working. Can someone help me please?
With an anchor tag, you only send a get request. If you want it to be put, you must create a form, and then add :
<input type="hidden" name="_method" value="PUT">
Another way to solve this issue is to use Ajax. Right now the page will get refreshed each time a user wants to up-vote a theme and that can be quite frustrating.
I think you should post to the back end using Ajax and on the success callback update the view with javascript. I recommend using Angular for the front end. It has all what you need and it is super simple to make an Ajax-request.
So, here's a quick example how you could use Angular + Laravel to make your web application work.
Front End
<html ng-app="exampleApp">
<head>
<title>MyTitle</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
</head>
<body>
<div ng-controller="ThemeController">
<ul>
<li ng-repeat="theme in themes">
<span><% theme.name %></span>
<p><% theme.description %></p>
<p><% theme.votes %></p>
Vote Up
</li>
</ul>
</div>
<script type="text/javascript">
var app = angular.module("exampleApp", [], function($interpolateProvider) {
// This we need to not collide with Laravel's {{ }}
$interpolateProvider.startSymbol('<%');
$interpolateProvider.endSymbol('%>');
});
app.controller('ThemeController', function($scope, $http) {
$scope.themes = [];
$scope.voteUp = function(theme) {
$http({
url: '/api/themes/voteUp',
method: 'POST',
data: {
id: theme.id
}
}).success(function(response) {
theme.votes += 1;
});
}
// On init we need to get the themes
$http({
url: '/api/themes',
method: 'GET'
}).success(function(themes) {
$scope.themes = themes;
});
});
</script>
</body>
</html>
Back End
Your routes
Route::get('api/themes', 'ThemeController#getFive');
Route::post('api/themes/voteUp, 'ThemeController#voteUp');
Your ThemeController
function getFive() {
return Theme::paginate(5);
}
function voteUp(Request $request) {
$theme = Theme::whereId($request->id);
$theme->votes += 1;
$theme->save();
return $theme;
}
This code is not tested. But I'll think you get the point!
I am trying to submit a form using AJAX and VueJs. But somehow I am failing to achieve that. I always end up getting an empty Illuminate\Http\Request object.
The blade file:
<body>
<div class="container">
<generate-admin></generate-admin>
</div>
<script src="https:http://code.jquery.com/jquery.js"></script>
<script src="{{ url('/js/main.js') }}"></script>
</body>
The component:
<template>
<form id="createAdministrator" #submit.prevent="createAdministrator">
<div class="form-group">
<input type="text"
name="username"
id="txtUserName"
placeholder="Username"
autocomplete="off"
v-model="username"
/>
</div>
<input type="submit" value="Submit">
</form>
</template>
<script>
export default {
data: function() {
return {
username: ''
}
},
methods: {
createAdministrator: function() {
formContents = jQuery("#createAdministrator").serialize();
this.$http.post('/admin', formContents).then(function(response, status, request) {
console.log(response);
}, function() {
console.log('failed');
});
}
}
}
</script>
main.js
import Vue from 'vue';
import GenerateAdmin from './components/GenerateAdmin.vue';
var VueResource = require('vue-resource')
Vue.use(VueResource);
Vue.http.headers.common['X-CSRF-TOKEN'] = document.querySelector('#token').getAttribute('content');
Vue.http.options.emulateJSON = true;
new Vue({
el: 'body',
components: { GenerateAdmin }
});
gulpfile.js
var elixir = require('laravel-elixir');
require('laravel-elixir-vueify');
elixir(function(mix) {
mix.browserify('main.js');
});
routes.php
Route::get('/admin/create', function () {
return view('admin.create');
});
Route::post('/admin', function(Request $request) {
// returns an empty object.
return response(['results' => $request]);
});
Route::get('/', function () {
return view('welcome');
});
What I get in return is:
"{"results":{"attributes":{},"request":{},"query":{},"server":{},"files":{},"cookies":{},"headers":{}}}"
When I check the Request Payload section of Network Tab in Chrome. I do see that the form is getting submitted successfully with whatever data I write in the text box above.
Why is this happening ? Kindly guide me where I have made the mistake ?
UPDATE 1:
I was playing trial and error with the code above. And I removed the namespace Illuminate\Http\Request and also removed the argument Request $request from the post Route. And changed the passing parameter to object from string.
Doing so, did the job for me that I was looking for. Why I don't know. I am still looking for someone who can explain this to me.
Why adding the namespace Iluminate\Http\Request in routes.php file didn't work as I was expecting and removing it did the task ?
Can anybody tell me why it didn't worked out earlier ? Any kind of help is highly appreciated.
P.S.: I have started learning VueJs Components recently.
As a general practice I follow, any form data which needs to be passed to the laravel controller is passed as json object from vue frontend. Then in laravel controller (route with a closure function in your case) the values from the received json object are retrieved by using $request->get('key').
So in your case the component code could be
<template>
<form id="createAdministrator" #submit.prevent="createAdministrator">
<div class="form-group">
<input type="text"
name="username"
id="txtUserName"
placeholder="Username"
autocomplete="off"
v-model="username"
/>
</div>
<input type="submit" value="Submit">
</form>
</template>
<script>
export default{
template:require('./generate-admin-template.html'),
data() {
return {
username: ''
}
},
computed:{
formData(){
return {
username:this.username
}
}
},
methods: {
createAdministrator: function() {
this.$http.post('/admin', this.formData).then(function(response) {
console.log(response);
}, function() {
console.log('failed');
});
}
}
}
</script>
Then in your routes.php file
<?php
use Illuminate\Http\Request;
/*
|--------------------------------------------------------------------------
| Application Routes
|--------------------------------------------------------------------------
|
| Here is where you can register all of the routes for an application.
| It's a breeze. Simply tell Laravel the URIs it should respond to
| and give it the controller to call when that URI is requested.
|
*/
Route::get('/', function () {
return view('welcome');
});
Route::get('/admin/create', function () {
return view('admin.create');
});
Route::post('/admin', function (Request $request) {
return response(['results' => $request->get('username')]);
});
I guess the Illuminate\Http\Request instance returns a $request - Collection so we need to access the values using Methods available on Collections.
I have tested the above code along with your code for main.js and '/admin/create'.
One more thing - I think if you send serialized form data to the controller, then within the controller it needs to be de-serialized in order to get object or array containing $key=>$value pairs to facilitate fetching required data.
All variables ($attributes, $request, $query, etc) on Request and SymfonyRequest classes are protected, since neither class implements __toString, php does its best to give you what it can.
If you need to see each value, you need to call correct getter. Something like:
Route::post('/admin', function(Request $request) {
return response(['server' => $request->server(), 'form'=>$request->all()]);
});
Is there a way to have bootstrap js directives (inline tag attributes) work within a angular template file?
All JS libs are correctly loaded, including the js init code for using popovers.
The angular template is correctly loaded using angular router.
All the bootstrap js functions fail to be run/detected in angular templates, is there something i'm doing wrong or is this expected, and is there a way to get it working without changing the html (I looked at angular bootstap ui, but it requires rewriting the html)
Super simplified:
Twig template:
<div class="col-md-12" ng-app="builderApp"><div ng-view></div></div>
Angular template:
<i class="fa fa-info-circle" data-toggle="popover" data-content="woop woop"></i>
Angular JS:
var builderApp = angular.module('builderApp', ['ngRoute', 'xeditable']);
builderApp.config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/', {
templateUrl: template_path + 'root.html',
controller: 'rootController'
})
}]);
builderApp.controller('rootController', function($scope, directoryFactory) {
$scope.directory = directoryFactory.getDirectory();
});
I would most certainly use the Angular Bootstrap Directive. I've never seen it done any other way. This will give you access to the typical bootstrap CSS as well as the interactive functions in the angular bootstrap. I also prefer to use ui router.
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css"/>
<script src="scripts/vendors/ui-router-master/release/angular-ui-router.min.js"></script>
<script src="scripts/vendors/ui-bootstrap-tpls-0.13.0.min.js"></script>
var app = angular.module('BuilderApp', ['ui.router','ui.bootstrap']);
app.config(['$stateProvider', '$urlRouterProvider',
function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("/login");
$stateProvider
.state('login', {
url: '/login',
title: 'Login',
templateUrl:'views/loginView.html',
controller: 'loginCtrl'),
})
.state('account', {
url: '/account',
title: 'My Account'
views: {
'navigation': {
templateUrl: 'views/navigationView.html',
controller: 'navigationCtrl'
},
'content': {
templateUrl: 'views/contentView.html',
controller: 'navigationCtrl'
}
}
})
.state('account.dashboard', {
url:'/dashboard',
title: 'Dashboard',
views : {
'pageContent': {
templateUrl:'views/dashboardView.html',
controller: 'dashboardCtrl'
}
}
})
And then make sure to inject the router into your controller.
app.controller('navigationCtrl', function ($scope, $stateParams, $location, $state) {