I am attempting to learn Vue.js. I'm working through building a very minimal component. The component is literally just an option list using select. Nowhere in the documentation, or any tutorials I can find online, does it show how to load data from database into a Vue component. I have found some examples using Axios, but I have no interest at all in using Axios. I am simply trying to learn how Vue works, so that I can see if I can use it to improve my workflow. This is literally a basic test case. Also, the PHP portion that this code is referencing works fine. I have tested it directly, and it loads the data exactly as expected.
Here is the javascript portion.
const cityChoice = {
data() {
return {
citys: [
{ Abbrev: 'Lima' },
{ Abbrev: 'FtWayne' },
],
err: false
}
},
methods: {
},
mounted() {
fetch('Controller/get_cities.php', {
method: 'POST', // *GET, POST, PUT, DELETE, etc.
cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
headers: {
// 'Content-Type': 'application/json'
'Content-Type': 'application/x-www-form-urlencoded',
},
redirect: 'follow', // manual, *follow, error
referrerPolicy: 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
body: '' // body data type must match "Content-Type" header
}).then(function (response) {
return response.text();
}).then(function (data) {
testData = data
return testData;
});
},
methods: {
getCities() {
fetch('Controller/get_cities.php', {
method: 'POST', // *GET, POST, PUT, DELETE, etc.
cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
headers: {
// 'Content-Type': 'application/json'
'Content-Type': 'application/x-www-form-urlencoded',
},
redirect: 'follow', // manual, *follow, error
referrerPolicy: 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
body: '' // body data type must match "Content-Type" header
}).then(function (response) {
return response.text();
}).then(function (data) {
this.citys = data;
alert(this.citys)
});
this.citys = [
{ Abbrev: 'Dayton' },
{ Abbrev: 'Cincy' },
]
}
}
}
Vue.createApp(cityChoice).mount('#cityChoice')
And here is the HTML portion.
<?php
$lifetime = 60 * 60 * 24 * 14;
session_set_cookie_params($lifetime, '/');
session_start();
include 'Controller/login_check.php';
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://unpkg.com/vue#next"></script>
<title>BAI Inventory Entry</title>
</head>
<body>
<div id="cityChoice">
<select id="city">
<option v-for="city in citys">
{{ city.Abbrev }}
</option>
</select>
<button v-on:click="getCities">Get Cities</button>
</div>
</body>
<script src="js/global.js?ver3"></script>
</html>
I am positive that I'm just not understanding how this software language works. But, I need to understand how it calls real data, or else I'm never going to be able to wrap my mind around the other basics of it, because I am constantly finding myself asking "why is this better than just coding it in javascript". I'm trying to see how to make this simple example work, so that I can get past that question in my head and move forward with learning the language.
I have tried this with using "mounted" and using "created" to load the getCities method, while having the data portion of cities set to ''. Still no dice. When hard coding the cities with an array and/or JSON data, it loads exactly as expected.
UPDATE: I have adjusted the code as what is now shown in the javascript section. Using chrome tools, I can see that my cities variable is filled with an array of JSON objects, but I'm still not getting any data into the Select list. I'm completely at a loss as to why this isn't working, as well as why this seems to be so ridiculously difficult to do. And...this is literally just code to load a few cities into a drop down list.
Update 2: Apparently Vue will not let the item be updated from inside of a Fetch. I have updated the code to show my testing. My API returns the data fine, and I have verified it multiple times. I have tried hard coding the this.citys inside of the final fetch .then portion, and it doesn't work. But, when I hard code it outside of the fetch (as shown in the code above), it works fine. I'm to the point where I have to assume this is a limitation of Vue, which seems pretty crazy to me. I found one other question on Stackoverflow that had this same problem, but the answer literally just tells him to do exactly what I've been trying to do above. And, I'm unable to comment to ask if he found a solution, because I don't have enough reputation.
//Html
<div id="cityChoice">
/* <select > to load options on mounted use mounted hook*/
/* <select v-on:click="getCities"> to load options on click(whatever event)*/
<option v-for="city in cities">
{{ city.City }}
</option>
</select>
</div>
var app3 = new Vue({
el: '#cityChoice',
data(){
return {
cities:[],
err:false
}
},
methods:{
async getCities() {
//fetch -> assumption: the php call works -> u can use postman to test this
let data = await fetch('Controller/get_cities.php', {
method: 'GET', // *GET, POST, PUT, DELETE, etc.
})
//Data will likely have a data.data field
if( data in data && !data.error){
//Set data
this.cities = data.data //this assumes that data.data is correctly formatted from ur php call
}else{
this.err = true
}
}
},
//Add if you want data loaded on paint
created(){
// or mounted(){
this.getCities()
}
})
See hello world example
https://codesandbox.io/s/github/vuejs/vuejs.org/tree/master/src/v2/examples/vue-20-hello-world
Found information at this question that led me to the answer to mine.
Updating a vuejs alert component from a fetch return value
I will include my updated code in case someone happens past this question instead of the one linked here.
I had to update the response.text() to response.json(), but the biggest issue was the problem of the this not being recognized inside of the fetch function. I knew that, but in the middle of learning vue, I thought this would behave differently.
const cityChoice = {
data() {
return {
citys: [
{ Abbrev: 'Lima' },
{ Abbrev: 'FtWayne' },
],
err: false
}
},
methods: {
},
mounted() {
var self = this;
fetch('Controller/get_cities.php', {
method: 'POST', // *GET, POST, PUT, DELETE, etc.
cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
headers: {
// 'Content-Type': 'application/json'
'Content-Type': 'application/x-www-form-urlencoded',
},
redirect: 'follow', // manual, *follow, error
referrerPolicy: 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
body: '' // body data type must match "Content-Type" header
}).then(function (response) {
return response.json();
}).then(function (data) {
self.citys = data;
});
},
methods: {
getCities() {
var self = this;
fetch('Controller/get_cities.php', {
method: 'POST', // *GET, POST, PUT, DELETE, etc.
cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
headers: {
// 'Content-Type': 'application/json'
'Content-Type': 'application/x-www-form-urlencoded',
},
redirect: 'follow', // manual, *follow, error
referrerPolicy: 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
body: '' // body data type must match "Content-Type" header
}).then(function (response) {
return response.json();
}).then(function (data) {
self.citys = data
});
}
}
}
Vue.createApp(cityChoice).mount('#cityChoice')
Hopefully this helps someone else who's trying to pick up the new language.
Related
I'm trying to test and learn how fetch works so I want to send some data from javascript to a php file, my problem is that I can't retrieve the data (in the php file), only getting a null response.
I'm using POST but I have tried with GET with the same result
As a side note, in console the conection in network only appears after I press F5 , as I understand it, to work should be already when I open Test.php.
datosJS.js
let datos = {
method: "POST",
headers: {
"Content-type" : "application/json"
},
body: JSON.stringify({
username:"Jonathan",
email:"jonathan#gmail.com",
password:"123456"
})
}
fetch('Test.php',datos)
.then(resp => resp.text())
.then(resp =>{
console.log(resp);
})
Test.php
<script src="datosJS.js" type="text/javascript"></script> //I use this to call "datosJS.js" to receive the data here in Test.php
<?php
$body = json_decode(file_get_contents("php://input"), true);
var_dump($body);
?>
I understand PHP is on server side and JS on client side and both of them run in different times, nevertheless I'm having troubles to find the solution to this problem.
Thank you for your help !
** Edited a small change in fetch which now let me see the data in console
Well finally I managed to get the solution to this, explanation is below:
datosJS.js
window.onload = function() {
let datos = {
method: "POST",
headers: {
"Content-type" : "application/json"
},
body: JSON.stringify({
username:"Jonathan",
email:"jonathan#gmail.com",
password:"123456"
})
}
fetch('Test.php',datos)
.then(resp => resp.text())
.then(resp =>{
console.log(resp);
document.getElementById('results').innerHTML = resp;
//document.querySelector('#results').innerHTML = resp; // works as well as getElementById
})
}
Test.php
<script src="datosJS.js" type="text/javascript"></script>
<section class="Section" id="results" name="results">
<?php
$body = json_decode(file_get_contents("php://input"), true);
$nombre = $body['username'];
echo $nombre;
echo '</br>';
print_r($body);
?>
Below I will mark what was lacking in the original code:
In datosJS.js document.getElementById('results').innerHTML = resp; and wrap everything in window.onload = function() {}
In Test.php add the id="results" name="results" to a div, section or whatever to receive from the innerHTML.
I hope it helps someone in the future. Cheers
After hours of trying is still can't get my React Expo application (localhost http://192.168.1.113:19006/#/) to connect to my PHP api that is hosted on an external server.
The header of my api file's is as following;
header("Access-Control-Allow-Origin: *");
//header("Access-Control-Allow-Headers: *");
//header("Access-Control-Allow-Credentials: 'true'");
header("Content-Type: application/json");
header("Access-Control-Allow-Methods: POST");
header("Access-Control-Max-Age: 3600");
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
When I use postman to connect and test mine /login.php file with the following json body;
POST to: www.URLofAPIlocation.nl/subFolder/api/login.php
{
"email" : "info#email.nl",
"password" : "Password12345"
}
The api returns the JWT token and succes message as expected.
{
"message": "Successful login.",
"jwt": "eyJ0eXA..... ( FULL TOKEN )"
}
But when I try to connect with the following functions within my react native application it try to uses the localhost base url and not the given;
async function postData(url = '', data = {}) {
const response = await fetch(url, {
method: 'POST',
mode: 'cors', // Without cors it fails.
cache: 'no-cache',
// credentials: 'same-origin', // Not sure if needed.
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'POST',
'Access-Control-Max-Age':' 3600',
},
redirect: 'follow',
referrerPolicy: 'no-referrer',
body: JSON.stringify(data)
});
return await response.json();
}
// https://www.URLofAPIlocation.nl/... and https://URLofAPIlocation.nl/ also not working
function login(){
postData('www.URLofAPIlocation.nl/subFolder/api/login.php', {
email : "info#email.nl",
password : "Password12345",
})
// Other option without error catching. (not working..)
// .then((data) => {
// console.log(data); // JSON data parsed by `response.json()` call
// });
.then(response => {
console.log(response)
return response.json()
})
.then(response => {
console.log("End query"+ response);
return response;
})
.catch(err => {
console.log("Error: "+err)
});
}
I'm not sure what I do wrong since every tutorial and documentation I find the exact same setup as I am using.
The error message is as following;
POST http://192.168.1.17:19006/www.URLofAPIlocation.nl/subFolder/api/login.php 404 (Not Found)
It seems like that react expo uses it's own location as the base url and adds the url of the fetch after it. The location of the api is off course without: http://192.168.1.17:19006//. I can't find where to change or remove this, so help would much be appreciated.
Thanks in advance!
Ps because of personal reasons I've hidden the exact web address of the api location and passwords. The api is hosted on an https domain and functions as expected.
Hello all and thanks in advance,
Short story, I am using a plugin to dynamically populate select options and am trying to do it via an ajax call but am struggling with getting the data into the select as the select gets created before the ajax can finish.
First, I have a plugin that sets up different selects. The options input can accept an array or object and creates the <option> html for the select. The createModal code is also setup to process a function supplied for the options input. Example below;
$('#modalAccounts').createModal({
{
component: 'select',
options: function () {
let dueDate = {};
for (let i = 1; i < 32; i++) {
dueDate[i] = i;
}
return dueDate;
}
}
});
What I am trying to do is provide an object to the options input via AJAX. I have a plugin called postFind which coordinates the ajax call. Items such as database, collection, etc. are passed to the ajax call. Functions that should be executed post the ajax call are pass through using the onSuccess option.
(function ($) {
$.extend({
postFind: function () {
var options = $.extend(true, {
onSuccess: function () {}
}, arguments[0] || {});
options.data['action'] = 'find';
$.ajax({
url: "../php/ajax.php",
type: "POST",
data: options.data,
statusCode: {
404: function () {
alert("Page not found");
}
},
success: function (result) {
var obj = $.parseJSON(result);
if (obj.success) {
if (typeof options.onSuccess === 'function') {
options.onSuccess.call(this, obj);
}
}
},
error: function (xhr, text, err) {
console.log(err);
}
});
}
});
}(jQuery));
The plugin works fine as when I look at the output it is the data I expect. Below is an example of the initial attempt.
$('#modalAccounts').createModal({
{
component: 'select',
options: function () {
$.postFind({
data: {
database: 'dashboard',
collections: {
accountTypes: {
where: {status: true}
}
}
},
onSuccess: function (options) {
let dataArray = {};
$.each(options, function (key, val) {
dataArray[val._id.$oid] = val.type;
});
return dataArray;
}
})
}
}
});
In differnt iterations of attempting things I have been able to get the data back to the options but still not as a in the select.
After doing some poking around it looks like the createModal script in executing and creating the select before the AJAX call can return options. In looking at things it appears I need some sort of promise of sorts that returns the options but (1) I am not sure what that looks like and (2) I am not sure where the promise goes (in the plugin, in the createModal, etc.)
Any help you can provide would be great!
Update: Small mistake when posted, need to pass the results back to the original call: options.onSuccess.call(this, obj);
I believe to use variables inside your success callback they have to be defined properties inside your ajax call. Then to access the properties use this inside the callback. Like:
$.ajax({
url: "../php/ajax.php",
type: "POST",
data: options.data,
myOptions: options,
statusCode: {
404: function () {
alert("Page not found");
}
},
success: function (result) {
var obj = $.parseJSON(result);
if (obj.success) {
if (typeof this.myOptions.onSuccess === 'function') {
this.myOptions.onSuccess.call(this);
}
}
},
error: function (xhr, text, err) {
console.log(err);
}
});
It's not clear to me where the problem is without access to a functional example. I would start with a simplified version of what you want to do that demonstrates the proper functionality. My guess is the callbacks aren't setup exactly correctly; I would want to see the network call stack before making a more definitive statement. A few well-placed console.log() statements would probably give you a better idea of how the code is executing.
I wrote and tested the following code that removes most of the complexity from your snippets. It works by populating the select element on page load.
The HTML file:
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
<select data-src='test.php' data-id='id' data-name='name'></select>
</body>
</html>
<html>
<script>
$('select[data-src]').each(function() {
var $select = $(this);
$select.append('<option></option>');
$.ajax({
url: $select.attr('data-src'),
data: {'v0': 'Alligator', 'v1': 'Crocodile'}
}).then(function(options) {
options.map(function(option) {
var $option = $('<option>');
$option
.val (option[$select.attr('data-id')])
.text(option[$select.attr('data-name')]);
$select.append($option);
});
});
});
</script>
And the PHP file:
<?php
header("Content-Type: application/json; charset=UTF-8");
echo json_encode([
[ 'id' => 0, 'name' => 'Test User 0' ],
[ 'id' => 3, 'name' => $_GET['v0'] ],
[ 'id' => 4, 'name' => $_GET['v1'] ]
]);
Here's a fiddle that also demonstrates the behavior.
In the middle of a PayPal Checkout Express (client-side) javascript, I need to use AJAX to call the output of a PHP page, but I'm a bit stuck.
The PHP page:
$data = array('retid' => $username);
header('Content-Type: application/json');
echo json_encode($data);
Now inside the other javascript page I simply want to capture the PHP variable $username, via AJAX, as a javascript variable.
<?php
$IDToPassPlus = ($id.'&retid=');
?>
<script>
//It's the inclusion of this part, which tries to get the "retid" js variable, that stops the script from rendering the Paypal button:
$.ajax({
type: 'POST',
url: 'test-call.php',
dataType: 'json',
success: function(response) {
var retid = response.data.retid;
},
});
paypal.Button.render({
env: 'sandbox',
client: {
sandbox: 'xxxxx',
production: 'xxxxx'
},
commit: true,
style: {
layout: 'vertical',
size: 'responsive',
shape: 'rect',
color: 'gold'
},
payment: function(data, actions) {
return actions.payment.create({
payment: {
transactions: [
{
amount: { total: '0.99', currency: 'GBP' }
}
],
redirect_urls: {
'cancel_url': 'pay-return-cancel.php?id=<?php echo $IDToPassPlus; ?>'+retid
}
}
});
},
onAuthorize: function(data, actions, error) {
return actions.payment.execute().then(function() {
window.alert('Payment Complete!');
window.location.replace('test-return.php?id=<?php echo $IDToPassPlus; ?>'+retid);
if (error === 'INSTRUMENT_DECLINED') {
actions.restart();
}
});
},
onCancel: function(data, actions) {
return actions.redirect();
},
onError: function(err) {
window.location.replace('pay-return-error.php?id=<?php echo $id; ?>'+retid);
}
}, '#paypal-button');
</script>
Without the contributor's AJAX suggestion, the button works perfectly. But I'm trying to pass a variable from a PHP page by way of AJAX, to add it onto the redirects.
it's possible to use on in-page javascript as
<script>
var js_var = "<?php echo $php_var;?>";
//now you have php var value in javascript to use on .php page
If it's not what you are seeking, then please elaborate your question.
ok so as far I understood you want to retrieve the PHP response via ajax and you don't know how to make ajax call. Here is an example you may use on your js file:
$.ajax({
type: 'POST',
url: 'YOUR PHP SCRIPT URL',
dataType: 'json',//this will make it understand what datatype to expect in response
success: function(response) {
var retid = response.data.retid; //here you get on successfull response
},
});
First, read this entire page; it will really help you throughout your career as a developer, it has helped me tremendously: https://stackoverflow.com/help/mcve
Then, lets use the knowledge gained from that page to make an MCVE. Put this on a new page:
$.ajax({
type: 'POST',
url: 'test-call.php',
dataType: 'json',
success: function(response) {
var retid = response.data.retid;
console.log(retid);
},
});
This should print the value of retid to your console. Take a look at your console. Notice any errors, or does the value of retid print as expected?
So why have we taken time to create a new page and put this on it? We are narrowing down our issue, we're trying to find the exact cause of the problem by creating an MCVE. If we don't know what is causing the problem, and if we can't create a very basic example to illustrate the problem, we will have a hard time solving the problem and/or asking for help.
(Note 1, make your code "pretty" when you post it here. Indent it as it should be indented; this makes it easier for others to read. You are asking people to take time out of their day to help you, for free; make it as easy as possible for them to read and understand your code)
(Note 2, here is an example of where I had some very, very complicated MySQL interactions that I had a question about. Rather than post all of the complicated code, I followed the MCVE concept: DRY - how to extract repeated code to...a stored function maybe? and made some fake, very very simplified examples of my problem. Since I did that, I was able to get quick, concise answers from experts, notice the answer I accepted was from one of the top-scored users on all of Stackoverflow)
I've Googled every instance of this error I can find, and none of the solutions work for me. In essence, I am doing what others have suggested. Despite that, I am receiving an error that my callback function is not being called. I am using Ajax/Jquery/JASONP to do a cross domain form submission using GET. Here is my code on the form side:
$(document).ready(function() {
$("#ajaxform1").submit(function(e){
e.preventDefault();
var surl = "http://blahblah/test_create_user.php?callback=?";
$.ajax({
type: 'GET',
url: surl,
crossDomain: true,
data: $('#ajaxform1').serialize(),
dataType: "jsonp",
success: function(msg) {
$.each(msg, function (index, value) {
if(value==1)
{
alert("New User Added");
} else {
alert("User Already Exists")
} }
});
},
error: function(xhr, status, error) {
var myerror = xhr+" "+status+" "+error;
alert("Failure Connecting to Kayako. Please Try Again("+myerror+")"); }
});
Here is the applicable snippet of my PHP Code:
if($USER_CHK->first()->id){
$data = array('msg' => '0'); // user exists
else {
$data = array('msg' => '1'); // User added
}
//echo customerAdded(FALSE);
header('Access-Control-Allow-Origin: '.$_SERVER['HTTP_ORIGIN']);
header('Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS');
header('Access-Control-Max-Age: 1000');
header('Access-Control-Allow-Headers: Content-Type, Authorization,X- Requested- With');
header("Content-type: application/json");
$data = array('msg' => '0');
print $_REQUEST['callback']. '('.json_encode($data).')';
exit;
});
});
My debugging shows that all form variables are getting posted.
The PHP code returns: jQuery11020900643879813015_1397599599587({"msg":"1"})
Yet the error indicating the callback was not called is thrown.
How does the request looks like on the server side?
I have a working example which is very similar to what you have. The only difference is that the content type I am replying with is:
'text/javascript'
Also, my JSONP message includes a semicolon at the end (which I think is not really a cause for failure).
returnJSONP = $_REQUEST['callback']. '('.json_encode($data).');';
If you were able to resolve, could you please post the solution?
I gave up trying to get this working and, instead, posted to a local php script which then used CURL to post to the remote server. I echo the CURL results back to the jQuery function and all works well.