I have an existing application that Im moving to Angular and I have some questions. My new Angular app has four routes:
Home
Activity
Login
Signup
In my old app I had AJAX calls to PHP that would query MySQL and return the information as needed, but I could tie everything together using jQuery and call my AJAX calls from one centrally located .js file.
Now, I need to write a call to $HTTP to do the same thing as my AJAX calls did, but I dont know where to put everything!
For example I have the following sample $HTTP function I found online:
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope, $http) {
$http.get("users.php")
.then(function(response) {
$scope.users = response.data;
});
});
</script>
Where does this go in the Angular file structure? I intend to call it from the Activity route, which creates another question. Since the route pages are based on templates how do I call the function from the route or template so I can see the results on the Activity page?
Factory/Service is what you are looking for. Ajax call should be made inside a factory method which in turn returns the data to the controller (myCtrl in your example).
You should bind your controller (myCtrl) with the view (Activity) in the route provider itself.
Here is an example that will give you a clear picture.
How factory works
Related
I am trying to get a laravel-nuxt project running. I am stuck with creating route calls to my laravel backend using axios async call to serve up data to my nuxt frontend before loading the page.
I am constantly getting getting a 404 with my current laravel-nuxt setup even though I have the route defined in api.php.
I am using this as a template for the project and I have not changed anything in that template yet:
https://github.com/cretueusebiu/laravel-nuxt
So my frontend call is this here:
async asyncData ({ $axios }) {
if (process.server) {
return $axios.$get('/api/data')
.then((res) => {
this.data = res.data;
})
}
}
And my backend route is defined as follows in api.php:
Route::get('/data', 'HomeController#index');
It always gives me a 404, is there something missing that I should be aware of?
According to the Readme in the Github project you have mentioned, you have to add your routes manually to
client/router.js
Read this line under Notes and follow the structure well you'll be able to avoid this.
This project uses router-module, so you have to add the routes
manually in client/router.js.
hope this helps.
I'm still a bit new to Vue.js, so I may be fundamentally misunderstanding something about the reactivity of it, but basically, I want to pass some data from PHP Laravel to a Vue.js component and have the Vue.js component automatically update when that data changes.
I've seen several similar posts on SO suggest that I use props to pass the data from a Laravel Blade template to a Vue.js component. Here's an example:
How to pass a PHP variable to Vue component instance in Laravel blade?
I have this working perfectly fine, but now I'm stuck with how to get the component to update when the data dynamically changes after page-load.
Specifically, I have a report table on a particular web page, and when the user clicks certain buttons, etc., I use Ajax to call a Laravel controller action that re-runs a query in my Laravel model to get the new data for the report.
I have the data in a PHP array / JSON, and that data is being properly returned to the client-side and I have access to it in the JS, but now, what do I need to do to force the report component in Vue.js to essentially re-render based on the data I just received? Is there a way to "update props" so that Vue.js detects the change and automatically re-renders the whole report component for me?
This is where I'm stuck, and after quite a bit of research, I can't find how to do this. Thank you.
Are you using Ajax outside of the Vue component? or within it as a method?
I have an example of how I dynamically update the Vue data from within the component itself. I'm not sure how to have external JS update the Vue component directly but I feel this is a good option to look at. I'm using axios instead of Ajax but the principle is the same (Axios is included by default in most Laravel installs past 5.5).
<template>
<div>
<div id="reports">
<!-- Display data -->
{{ reports }}
</div>
<button #click="refreshReports">Refresh</button>
</div>
</template>
<script>
export default {
data() {
return {
endpoint: '/api/MY_ROUTE/'
};
},
props: {
reports: Object
},
methods: {
// Make Axios call to API endpoint
refreshReports() {
// GET version
axios.get(this.endpoint)
.then(({data}) => {
this.reports = data.data;
});
// POST version
axios.post(this.endpoint, {
KEY: 'VALUE',
}).then(({data}) => {
this.reports = data.data;
});
/*
`data.data` assumes the returned response is a JSON Resource
if it's not returning the correct data, put a `console.log(data)` and see how it's getting returned!
*/
}
}
};
</script>
Where in your routes/api.php file you have a route like this:
// GET version
Route::get('MY_ROUTE', 'ReportController#getReports');
// POST version
Route::post('MY_ROUTE', 'ReportController#getReports');
And your Controller would have some method like this:
// app/Http/Controllers/ReportController
public function getReports(Request $request) {
return Reports::all();
}
Does that make sense?
Update:
I'm not sure how to have external JS update the Vue component directly
I know you can import external JS scripts and use their functions in methods but I've never done it that way before.
Something like:
<script>
import { myFunction } from '../external.js'
export default {
methods: {
refreshReports() {
// I have no idea if this is the correct way to do it, just a guess!
this.reports = myFunction();
}
}
};
</script>
When using laravel routing I write my links this way:
mywebsite.com/category/product
But to call ajax I would like instead:
mywebsite.com?author=&article=
And for _POST then
mywebsite.com/php/includes/dostuff.php
(The previous links are only examples)
As stated in the Laravel API documentation you could do something like
$query = $request->query();
to get all the url query ($_GET) items.
Source: https://laravel.com/api/5.3/Illuminate/Http/Request.html#method_query
Hope this helps
You just use normal routing when it comes to making ajax calls.. There is many ways you can go about it and two simple ways would be:
Set the post route for your '/' (Home page or root page) to aim at a controller if you dont have any other post requests that are made to the '/' page or route..
Route::post('/', 'AjaxController#WhatEverMethod');
If you already have other post requesting routes that point to ('/') then you can put a if statement to see if the request is Ajax and if it is then use the Ajax controller else use your normal controller.
My second simple solution would be to set a dedicated route that will handle your Ajax calls so for example:
Route::any('/Ajax/', 'AjaxController#index');
public function index(Request $request)
{
if($request->ajax()){
return "Is an ajax call..";
}
return "Is not an ajax call";
}
There should be no reason why you cant easily resolve this issue, Checkout laracasts, That might give you a good head start.
I'm creating a web app without any framework and I need a route. So i found AltoRoute as interesting solution. But I really don't understand how this working, I have read the documentation page but I have some question to ask. Hope that some one could help. I'll organize the question in step for more precision:
How can I import the controllers?
my app structure look like this:
PUBLIC HTML
App_name
APPLICATION
CONTROLLERS
LIBRARIES
MODELS
VIEW
SYSTEM 'in this folder I have inserted altoroute
I have all the controllers and the php backend inside the application folder. I want import all controllers available in controllers folder in AltoRouter. I tried with this:
require "AltoRouter.php";
$router = new AltoRouter();
$router->setBasePath("/App_name/system");
$router->map("GET|POST", "../application/controllers/backend.php");
is this good for import the controller?
How I can call specific function of the controller loaded?
In the past when I use CodeIgniter I perform this operation for load a function inside the controller:
$this->load->model('backend');
$this->backend->anon_function($foo); // call my personal function inside the controller
how I can do this when I loaded the controllers from AltoRouter?
How I can perform an Ajax call from javascript?
the good thing of the route is this, call a function inside the controller from javascript, in the past with CodeIgniter I use:
$('#login-form').submit(function(event)
{
var postUrl = GlobalVariables.baseUrl + 'user/ajax_check_login';
var postData =
{
'username': $('#username').val(),
'password': $('#password').val()
};
$('.alert').addClass('hidden');
$.post(postUrl, postData, function(response)
{
so how you can see I call ajax_check_login available in the user controller.
So, someone could help me to understand better all this steps? I'm new on route, so I need very an help to understand this..
Ok so Ive got this Javascript file, simply:
$(document).ready(function() {
$('.status').prepend("<div class='score_this'>(<a href='#'>score this item</a>)</div>");
$('.score_this').click(function(){
$(this).slideUp();
return false;
});
$('.score a').click(function() {
$(this).parent().parent().parent().addClass('scored');
$.get("/js/Rating.php" + $(this).attr("href") +"&update=true", {}, function(data){
$('.scored').fadeOut("normal",function() {
$(this).html(data);
$(this).fadeIn();
$(this).removeClass('scored');
});
});
return false;
});
});
Where it says /js/Rating.php, that file is in application/modules/recipes/models/Rating.php, this is because it contains some Zend logic that cant be accessed outside the application.
Through the Controller. That is the only reasonable way.
Remember JavaScript is executed on the client side, not the server. You placed your models outside the publicly accessible webroot, because your users are supposed to access your MVC app (e.g. the domain logic in the Rating model) through your app's FrontController and not on the Model directly.
In other words, since .get() issues an Ajax Request, you should direct this request to the Ratings controller in your app and make the Ratings controller call the appropriate model in your application. The model returns something to the controller and the controller then returns this result to the client.
Example:
$.get("/rating/update/someParamId/someParamValue");
This assumes you are using the default rewrite rules. In your controller you could then do $this->getRequest()->getParam('someParamId') and it would contain 'someParamValue'. The controller will return the ViewScript usually rendered by the action back to the client, so you might want to disable the layout to just return the HTML fragment.