Backbone.js Collections not applying Models (using Code Igniter) - codeigniter

I'm attempting to develop a site using CodeIgniter and Backbone.js, but I'm running into an issue when attempting to set Models to a Collection I have called fetch() on. I am using the REST API by Phil Sturgeon, and am receiving a JSON response when using fetch() on the Collection, but no children Models are added to it.
Here's the javascript I'm using:
$(document).ready(function() {
window.Person = Backbone.Model.extend({});
window.People = Backbone.Collection.extend({
model: Person,
url: "/api/content/users/format/json"
});
});
And my CI Controller:
require APPPATH.'/libraries/REST_Controller.php';
class Content extends REST_Controller {
function users_get() {
$users = array(
array('id' => 1, 'name' => 'Some Guy', 'email' => 'example1#example.com'),
array('id' => 2, 'name' => 'Person Face', 'email' => 'example2#example.com')
);
if($users) {
$this->response($users, 200); // 200 being the HTTP response code
} else {
$this->response(array('error' => 'Couldn\'t find any users!'), 404);
}
}
}
And when attempting to fetch() the Models for the Collection via the console like:
peoples = new People();
peoples.fetch();
peoples.models;
It gets the JSON response, but still says 'There are no child objects' (see image):
http://i.stack.imgur.com/e5vZv.png
Any idea what is going wrong? Totally stumped!

Explications
It's normal that people.models is empty directly after the fetch() call, you need to wait the end of the ajax request.
Indeed, fetch() is asynchronous and the Backbone JS documention says :
collection.fetch([options])
[...] The options hash takes success and error callbacks which will be passed (collection, response) as arguments.
Source: http://documentcloud.github.com/backbone/#Collection-fetch
Solution
You need to use :
peoples = new People();
peoples.fetch({
success: function (collection, response) {
// The collection is filled
console.log('Models : ', peoples.models);
}
});

Related

InertiaJs Redirect returns 302 but doesn't render

Really sorry if this has been covered before but I can't find a working solution and have even asked numerous work colleagues.
I have a form which sends a POST request to my MailController, validation and everything works just as expected, but on success, I want to redirect to a Thank you page. The Post request returns either a 200 or 302 depending on the method I try but every time it only sends the HTML to the response and doesn't render the component.
I can, however, navigate to that page if I visit the URL and it loads perfectly.
I've tried
to_route
Inertia::render
Redirect()
Redirect()->route()
Redirect::route()
even sending it in response, catching it in Axio's request in the component, and redirecting from there.
This is driving me nuts I just can't see what I'm doing wrong.
TIA for your help and suggestions
//controller
<?php
namespace App\Http\Controllers;
use ...
use Inertia\Inertia;
use...
class MailController extends Controller
{
public function sendEmail(Request $request)
{
$contact = $request->validate([
......
],[
.......
]);
Mail::to('email#email.co.uk')->send(new ContactEmail($contact));
return Redirect::route('thankyou');
// return response()->json([
// 'data' => $contact,
// 'message' => 'Message sent successfully.',
// 'redirect' => route('thankyou')
// ], 201);
}
}
// route
Route::get('/thankyou', function () {
return Inertia::render('Thankyou');
})->name('thankyou');
// submit function
submitContact: function () {
axios.post('/email', this.contact)
.then(response => {
console.log(response.data.redirect);
// if (response.data.redirect) {
// return Inertia.location(response.data.redirect);
// }
}).catch(err => {
const errors = err.response.data.errors;
if (err) {
Object.keys(errors).forEach(key => {
this.errors[key] = errors[key][0];
});
}
})
}

How to fix Paypal Checkout Order Creation Error

I am using Laravel 8 framework for PHP and I am trying to integrate paypal into my the local web.
However I am stuck on `create_order_error` even though I have strictly followed some sample snippets provided by paypal I still encounter this pro
References:
https://developer.paypal.com/demo/checkout/#/pattern/server
https://github.com/paypal/Checkout-PHP-SDK#code
https://developer.paypal.com/docs/checkout/reference/server-integration/
Error:
SyntaxError: Unexpected token < in JSON at positio…1kLoyti46gxJY-Rl1PH23n49yWhf&currency=PHP:2:79380"
Code:
<script>
// Render the PayPal button into #paypal-button-container
paypal.Buttons({
style: {
shape: 'pill',
layout: 'horizontal',
color: 'blue',
height: 35
},
// Call your server to set up the transaction
createOrder: function(data, actions) {
return fetch('/billing/createOrder', {
method: 'post',
headers: {
'content-type': 'application/json'
}
}).then(function(res) {
return res.json();
}).then(function(orderData) {
return orderData.id;
});
},
}).render('#paypal-button-container');
</script>
Note: I have removed the onApprove function since I'm stuck on createOrder
Controller
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use PayPalCheckoutSdk\Core\PayPalHttpClient;
use PayPalCheckoutSdk\Core\SandboxEnvironment;
use PayPalCheckoutSdk\Orders\OrdersCreateRequest;
use PayPalCheckoutSdk\Orders\OrdersCaptureRequest;
use PayPalHttp\HttpException;
class PaypalCheckoutController extends Controller
{
private $environment;
private $client;
public function __construct()
{
$this->environment = new SandboxEnvironment(config('paypal.client_id'), config('paypal.secret'));
$this->client = new PayPalHttpClient($this->environment);
}
public function index(Request $request)
{
return view('payment.checkout');
}
public function createOrder(Request $request)
{
$order = new OrdersCreateRequest();
$order->prefer('return=representation');
$order->body = array(
'intent' => 'CAPTURE',
'application_context' =>
array(
'return_url' => 'http://dummyweb.test/billing/checkout',
'cancel_url' => 'http://dummyweb.test/billing/checkout'
),
'purchase_units' =>
array(
0 =>
array(
'amount' =>
array(
'currency_code' => 'PHP',
'value' => '420.00'
)
)
)
);
try {
$result = $this->client->execute($order);
return $result;
}
catch(HttpException $ex) {
print_r($ex->getMessage());
}
}
}
SyntaxError: Unexpected token < in JSON at positio…
You are returning things other than JSON when the browser calls /billing/createOrder. You must only return JSON.
Use the Network tab in your browser's Developer Tools, or load the path in a new tab, to inspect the Response Body of what you are actually returning.
It will clearly be something other than JSON. Based on that error message it will start with some HTML (the < character)
Only return JSON. You need to be able to copy the entire Response Body into a JSON validator and have it be OK.
try
return response()->json($result);
and in the fetch request add header
Accept: 'application/json'

Foursquare API over Axios (Ajax) in Laravel not returning any data (500 internal server error)

So I'm trying to get company details via the Foursquare API after a user gives in a business name and a location name.
For example: "Huntrs" and "Brussel" should get this business' details via Foursquare API and then return them.
So far i'm trying to do this over Axios to make an Ajax call within the Laravel framework.
ajax.js - Axios call:
//Ajax function to get company details when the getCompanyDetails() function is called on a btn click
function getCompanyDetails(){
//Get company name and location from form
let businessName = document.querySelector('#businessName').innerHTML;
let businessLocation = document.querySelector('#businessLocation').innerHTML;
//Make the actual API GET request
axios.post('/getcompanydetails', {
params: {
businessName: businessName,
businessLocation: businessLocation
}
})
.then(res => {
console.log(res);
console.log(res.data);
//Add response data to empty form fields
})
.catch(function (error) {
//Log request error in console, maybe also show onpage?
console.log(error);
})
}
web.php - Routing
Route::post('/getcompanydetails', 'AjaxController#getCompanyDetails'); //Route for ajax call made from JS file ajax.js
AjaxController.php - Controller that handles Guzzle request to API for ajax calls
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use GuzzleHttp\Exception\GuzzleException;
use GuzzleHttp\Client;
class AjaxController extends Controller
{
//Make Foursquare API request with Guzzle!
public function getCompanyDetails() {
//Get params back from the Axios get Request
$params = json_decode(file_get_contents("php://input"),true);
$location = $params['businessLocation'];
$companyName = $params['businessName'];
//Setup actual Guzzle request
$client = new Client();
$result = $client->request('GET', 'https://api.foursquare.com/v2/venues/search', [
'query' => [
'client_id' => env('FOURSQUARE_CLIENT_ID'),
'client_secret' => env('FOURSQUARE_SECRET_ID'),
'v' => "20191009",
'near' => $location,
'query' => $companyName,
'limit' => 1
]
]);
//Return $result in JSON format to ajax.js
return response()->json($result);
}
}
As Saly 3301 said i had to check the network tab:
network -> preview tab in chrome dev tools
This said the businessLocation index was undefined.
Solution:
Within the ajax.js, I removed the params{} around my actual name and location parameters and that stops the 500 internal error.
As such:
axios.post('/getcompanydetails', {
businessName: businessName,
businessLocation: businessLocation
})

Error with ajax and zf2 controller action

I was trying to use ajax to redirect to a controller action in zend framework 2 but the ajax is not responding rightly as well as I am not receiving the data alert.
Here is the ajax code:
$(".save_btn").click(function (){ //the class of submit button is save_btn
$.ajax({
type : 'POST',
url : '/template/addtemplate',
data : {'id':'test'},
success : function(data,status)
{
alert(data.message);
}
});
});
this is my controller code:
public function addtemplateAction()
{
$result = array('status' => 'error',
'message' => 'There was some error. Try again.'
);
$request = $this->getRequest();
if($request->isXmlHttpRequest()){
$data = $request->getPost();
if(isset($data['id']) && !empty($data['id'])){
return new JsonModel($result);
$result['status'] = 'success';
$result['message'] = 'We got the posted data successfully.';
}
}
return new JsonModel($result);
}
I have also added these particular things in my module.config.php file :
'strategies' => array (
'ViewJsonStrategy'
),
I think the problem lies in $request->isXmlHttpRequest() which returns blank.
Any help will be accepted..
Use any kind of developer tools. Chrome => f12 => Network tab and check your response

issues with backbone.js DELETE request and codeigniter restserver (phils)

I'm sure this is something I'm doing wrong, but I can't seem to figure it out. I'm using backbone.js to talk to my rest server (Philip Sturgeon's codeigniter restserver). I am running a normal model.destroy() on one of my backbone collections model.
//a basic example
tagCollection.at(5).destroy();
This creates a proper call to a url like:
DELETE http://mydomain.com/index.php/tags/tag/id/12
When I get inside my "tag_delete" php function, and do:
$this->delete('id');
This always returns nothing. I assume this has something to do with the way backbone.js sends it's requests, but nothing is jumping out at me. Details below.
Backbone is issuing a "DELETE" request.
Relevant code from my REST_Controller method:
function tag_delete () {
//delete the tag
$id = $this->delete('id'); //always empty
$result = $this->tag_model->delete($id);
if (! $result) {
$this->response(array('status' => 'failed'), 400);
}
$this->response(array('status' => 'success'), 200);
}
Any ideas? Any backbone.js experts run into this when using codeigniter and Philip Sturgeon's restserver?
This should be a cheap quick way to fix your delete request...
function tag_delete () {
$id = $this->uri->segment(4);
$result = $this->tag_model->delete($id);
if (! $result) {
$this->response(array('status' => 'failed'), 400);
}
$this->response(array('status' => 'success'), 200);
}
However, this is how I am structuring my requests using a combo of backbone and REST_Controller...
DELETE http://example.com/index.php/tags/12
(get rid of the /tag/id/ segment of the url... it's implied that you are deleting a 'tag' row from the 'tags' collection by id, appending /tag/id is unnecessary)
function tag_delete ($id) {
$result = $this->tag_model->delete($id);
if (! $result) {
$this->response(array('status' => 'failed'), 400);
}
$this->response(array('status' => 'success'), 200);
}
for the collection:
Backbone.Collection.extend({
url : '/tags'
});
tagCollection.at(5).destroy();
Then add something like this to your routes:
$route['tags/(:num)'] = 'tags/tag/$1';
which will set up the structure necessary for the restserver controller... it is just much more manageable that way if you are doing a lot of Backbone work.
As per tgriesser's suggestion, the best way to do this is to use the url property on the collection. I have used the following before and it works like charm (the following controller implemented using silex framework + paris library for data access):
// DELETE /{resource}/{id} Destroy
$app->delete('/api/todos/{id}', function ($id) use ($app) {
$todo = $app['paris']->getModel('Todo')->find_one($id);
$todo->delete();
return new Response('Todo deleted', 200);
});
In your backbone collection, add the following:
window.TodoList = Backbone.Collection.extend({
model: Todo,
url: "api/todos",
...
});
Recently, I have written a tutorial on how to do GET/POST/PUT/DELETE with Backbone.js and PHP http://cambridgesoftware.co.uk/blog/item/59-backbonejs-%20-php-with-silex-microframework-%20-mysql, might be helpful.

Resources