well, you are trying to send a json string followed by another json string…
I’ve taken the liberty to clean up your code a bit so others can read it more easily
Your controller:
public function index(){
$country = $this->Countries->find('all')->extract('name');
$this->set(compact('country'));
}
public function getStates(){
$state = $this->States->find("all");//->extract('name');
return $this->response
->withType('application/json')
->withStringBody(json_encode([
'state' => $state,
'result' => $result
]));
}
public function getCities(){
$city = $this->Cities->find()->extract('name');
return $this->response
->withType('application/json')
->withStringBody(json_encode([
'state' => $state,
'result' => $result
]));
}
The form:
<?= $this->Form->control('country_name', [
'options' => $country,
'empty' => 'Select Country',
'id' => 'country'
]); ?>
Your JS code:
$(function(){
$('#country').on('change', function() {
var id = $(this).val();
var targeturl = '<?= Router::url(["controller"=>"homes","action"=>"getStates"]); ?>';
if(id == '-1'){
$('#state').html(`<option value="-1">Select State</option>`);
}else{
$("#divLoading").addClass('show');
$('#state').html(`<option value="-1">Select State</option>`);
$.ajax({
type:'post',
url: targeturl,
data:'id='+id+'&type=state',
dataType: 'json',
success:function(result){
// $("#divLoading").removeClass('show');
// $('#state').append(result);
}
});
}
});
});
I don’t know whether using the return $this->response
is the “proper” way to do it but it works for me (feel free to correct any mistakes I may have made)