I have a problem with Ajax. I have a controller where is get response from external API. In this controller are passing variables to API request. The result is passing to a view. On this view I have drop down list with currency's. I want when user select another currency the new request will be send to API and generate new view.
Below is file and code.
web.php
Route::get('/home', 'HomeController@nbp');
Route::post('/home','HomeController@nbp');
HomeController.php
public function nbp(Request $request)
{
$data = $request->all();
if($request->ajax() && $request->isMethod('post')){
$data = response()->json($data);
$data = $data->getContent();
$data = json_decode($data, true);
$currency = $data['currency'];
Debugbar::info($currency);
}else{
$currency = 'EUR';
}
$tabeA = 'a';
// Create a client with a base URI
$client = new GuzzleHttpClient(['base_uri' => 'http://api.nbp.pl/api/'],['headers'=>['content-type'=> 'application/json']]);
// Send a request
$response = $client->request('GET', 'exchangerates/rates/'.$tableA.'/'.$currency);
$response->getStatusCode();
// 200
//$contentType = $response->getReasonPhrase();
// 'application/json; charset=utf8'
$currency = json_decode($response->getBody());
$data = $currency->rates;
$data2 = $data[0]->mid;
if($request->ajax() && $request->isMethod('post')){
return view('home',compact('currency'))->render();
}else{
return view('home',compact('currency'));
}
}
script.js
$('#currencyNameA').change(function() {
$.ajax({
type:'post',
dataType: 'json',
headers: {'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')},
url: '/home',
data: { currency : $('#currencyNameA').val()},
success: function(data){
},
complete: function(data){
}
});
});
The request to API must be http://api.nbp.pl/api/$table/$currency
Example: http://api.nbp.pl/api/a/USD
Do the following:
Return json from your controller if you do a ajax call:
$currency = json_decode($response->getBody());
$data = $currency->rates;
$data2 = $data[0]->mid;
if($request->ajax() && $request->isMethod('post')){
return response()->json(["currency"=>$currency]);
}else{
return view('home',compact('currency'));
}
in the success function output the data to the page
success: function(data){
$('body').append(data.currency.rates[0].mid);//change the body element with your element
},
VIEW
@extends('layouts.app') @section('content')
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">Currency</div>
<div class="panel-body">
{!! Form::open(array('url' => '/currency','method' =>'post')) !!}
{!! csrf_field() !!}
<select name="currency" id="currencyNameA">
@foreach($currency_table_A->rates as $rows)
<option value="{{ $rows->code }}">{{ $rows->currency }}</option>
@endforeach
</select>
{!! Form::close() !!}
<br />
<h2>
<div class="currency" id="ajax_currency">currency {{$currency->currency}} {{ $currency->rates[0]->mid}} last update was {{ $currency->rates[0]->effectiveDate }}</div>
</h2>
</div>
</div>
</div>
</div>
</div>
@endsection
Controller
public function nbp(Request $request){
if($request->ajax() && $request->isMethod('post')){
$cur = $request->input('currency'); //get currency from post
//Debugbar::info($cur);
}else{
$cur = 'EUR';
}
$tabeA = 'a';
// Create a client with a base URI
$client = new GuzzleHttpClient(['base_uri' => 'http://api.nbp.pl/api/'],['headers'=>['content-type'=> 'application/json']]);
// Send a request
$response = $client->request('GET', 'exchangerates/rates/'.$tableA.'/'.$cur);
$response->getStatusCode();
// 200
//$contentType = $response->getReasonPhrase();
// 'application/json; charset=utf8'
$currency = json_decode($response->getBody());
$data = $currency->rates;
$data2 = $data[0]->mid;
if($request->ajax() && $request->isMethod('post')){
return response()->json(['currency' => $data, 'mid' => $data2, 'updated' => $currency->rates[0]->effectiveDate]);
}else{
return view('home', compact('currency'));
}
}
JS
$('#currencyNameA').change(function() {
$.ajax({
type:'post',
dataType: 'json',
headers: {'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')},
url: '/home',
data: { currency : $('#currencyNameA').val()},
success: function(data){
$('#ajax_currency').html('currency '+data.currency+' '+data.mid+' last update was '+data.updated);
},
complete: function(data){
//ajax complete
}
});
});
When user loads the page (not Ajax) a view will render with all ur data that u compact
When user triggers the select change a ajax call will be made and you will recieve a json data (array)
and this data you will fill inside div
called ajax_currency
(where you echo your data from normal page visit) hope it is clean now.
This way you dont rerender a view you just change a piece of it via JS.
OK maybe one more time because we probable misunderstand.
I have a view:
@extends('layouts.app') @section('content')
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">Currency</div>
<div class="panel-body">
{!! Form::open(array('url' => '/currency','method' =>'post')) !!}
{!! csrf_field() !!}
<select name="currency" id="currencyNameA">
@foreach($currency_table_A->rates as $rows)
<option value="{{ $rows->code }}">{{ $rows->currency }}</option>
@endforeach
</select>
{!! Form::close() !!}
<br />
<h2><div class="currency">
currency {{$currency->currency}} {{ $currency->rates[0]->mid}} last update was {{ $currency->rates[0]->effectiveDate }}
</div>
</h2>
</div>
</div>
</div>
</div>
</div>
@endsection
And a controller:
public function getCurrency(Request $request)
{
$client = new GuzzleHttpClient(['base_uri' => 'http://api.nbp.pl/api/'],['headers'=>['content-type'=>
'application/json']]);
//Table for dropdown list Begin
$table_response = $client->request('GET','exchangerates/tables/a');
$currency_table_A = json_decode($table_response->getBody());
$currency_table_A = $currency_table_A[0];
//Table for dropdown list End
if($request->ajax() && $request->isMethod('post')){
$cur = $request->input('currency'); //get currency from post
}else{
$cur = 'EUR';
}
// Send a request to External API
$response = $client->request('GET', 'exchangerates/rates/a/'.$cur);
//Antwser from External API
$currency = json_decode($response->getBody());
if($request->ajax() && $request->isMethod('post')){
//In Debug bar i get reply form API but my View is not change
Debugbar::info($currency);
return response()->json(view('curentCurrency', compact('currency','currency_table_A'))->render());
}else{
return view('curentCurrency', compact('currency','currency_table_A'));
}
}
Script.js
$('#currencyNameA').change(function() {
$.ajax({
type:'post',
dataType: 'json',
headers: {'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')},
url: '/currency',
data: { currency : $('#currencyNameA').val()},
success: function(data){
}
});
});
I need to pass a new answer to a View when was select new currency in drop list. When page is loaded first time i need to get basic value in USD when someone change from drop down list the currency result should change for that user choose.