Using redux-api-middleware which works similarly to axios and jquery.ajax, I passed a formData which is a mixture of an image and other form values as you can see on this image:
The problem I have is that after successfully calling the API via a POST request, the PHP $_POST object is null though there was an actual POST request happening. This is my code snippet:
import { CALL_API } from "redux-api-middleware";
export function createTestAnnouncement(data) {
return (dispatch, getState) => {
const { auth: { oauthToken, oauthTokenSecret } } = getState();
const formData = new FormData();
Object.entries(data).forEach(([key, value]) => {
if (key === 'image') {
formData.append(key, value);
} else {
formData.set(key, value);
}
});
return dispatch({
[CALL_API]: {
endpoint: "/api/test-announcements",
method: "POST",
headers: {
'xoauthtoken': oauthToken,
'xoauthtokensecret': oauthTokenSecret,
},
body: formData,
types: [CREATE_TEST_ANNOUNCEMENTS, CREATE_TEST_ANNOUNCEMENTS_SUCCESS, CREATE_TEST_ANNOUNCEMENTS_FAILURE]
}
})
}
}
How will be able to get values from the $_POST object? Did I use the FormData object correctly?
EDIT: My Controller is just this, PS: I am sure this working because this is working on a plain application/json request
use api\controllers\BaseController;
use model\Operations\TestAnnouncements\TestAnnouncementOperation;
use model\DB\TestAnnouncement;
class IndexController extends BaseController
public function actionCreate()
{
var_dump($_POST);
// Commented this out because the payload is not JSON
// $request = \Yii::app()->request;
// $op = new TestAnnouncementOperation();
// $op->topic = $request->getJSON('topic');
...
}
...
I always get a NULL on my var_dump. While using postman and passing form-data on the body generates me a value on my $_POST.
you can check if the variable is set or not using...
if(!isset($_POST["ur_varible_name_from_html_form"]))
{
echo "error";
}
You can see redux-api-middleware repo on github, issues #125. They already have resolved and given example [CALL_API] and [RSAA] with from data.
Related
I'm working on react native project, and i'm calling API and extracting data from it , the data is succesfully extracted but I want to take arguments from the extracted data and I did'nt know how
This is the code for fetching api :
Axios({
url: '/Authentification',
method: 'get',
baseURL: 'http://smart.netrostercloud.com/api',
transformRequest: [
function (data, headers) {
return data;
},
],
transformResponse: [
function (data) {
// console.log(data);
setData3(data);
},
],
headers: {
Authorization: 'Basic UxvwJc1GWjkOCyZoIHGuCD05gDUB72sqrgK30FgILho=',
},
});
console.log(data3);
I've used data3 to extract the data in my main function so it can be visible.
This is the data :
I want to take CompanyCode,UserName,Password,FirstName and LastName
Firstly : axios its n asynchronous function, so its return a promise,
Actually i dont prefere use this patern in simple api call l, but its good way if you know this concept and use oop like create instance of axios to reusable and cancel connectiin when component will unmount.
Fot this i prefere use this way
Const getUserData= async () =>{
try {
Const {data} = await axios.get(baseurl+route, headers , options)
data & & SetData({username:data. User. Username,........... } )
Dosomthing...
}
Catch(error) {
Dosomthing...
}
Before you storing data into data3 you need to stringify the data like this setData3(JSON.stringify(data));
and then try this:
if (data3) {
const COMP_NAME = data?.user?.CompanyCode;
const USER_NAME = data?.user?.UserName;
CONST FIRST_NAME = data?.user?.FirstName;
CONST LAST_NAME = data?.user?.LastName;
}
I am trying to dynamically build an axios get request, and have currently hardcoded some values in my parameters array to test with like so:
const parameters = [
'table=cumulative',
'where=koi_disposition like \'CANDIDATE\' and koi_period>300 and koi_prad<2',
'order=koi_period',
'format=json'
];
let searchParameters = '';
const api = axios.create({
baseURL: 'https://exoplanetarchive.ipac.caltech.edu/cgi-bin/nstedAPI/nph-nstedAPI'
});
for (let element in parameters) {
if (element !== '') {
searchParameters += `?${parameters[element]}`;
}
}
I then add this query to my axios get request below:
export const getExoplanets = async () => {
try {
searchParameters = searchParameters.replace(/;/g, "");
console.log(`${searchParameters}`);
return await api.get(`${searchParameters}`);
// return await api.get(`?table=cumulative&where=koi_disposition like 'CANDIDATE' and koi_period>300 and koi_prad<2&order=koi_period&format=json`);
} catch (error) {
return error;
}
};
When the variable version runs the api returns the error:
ERROR
Error Type: UserError
Message: Constraint contains an illegal keyword: ";"
However when the commented out, hard coded version runs it works just fine. At some point an extra semicolon is being added to the request. I assume it is being added at the end, but I can't find where or how. Any ideas how to fix this?
Axios supports easy query parameters using the params config option.
Just provide an object of key / value pairs and Axios will do all the encoding for you
const params = {
table: "cumulative",
where: "koi_disposition like 'CANDIDATE' and koi_period>300 and koi_prad<2",
order: "koi_period",
format: "json"
}
return api.get("", { params })
// or return api.get("", { params: params })
This will send a request to
?table=cumulative&where=koi_disposition+like+%27CANDIDATE%27+and+koi_period%3E300+and+koi_prad%3C2&order=koi_period&format=json
it seem you having an issue in this bellow line you have used the \ rest of this you can wrap all the things in the double quote.
'where=koi_disposition like \'CANDIDATE\' and koi_period>300 and koi_prad<2',
"where=koi_disposition like 'CANDIDATE' and koi_period>300 and koi_prad<2",
I can't figure out how to URL encode array params in an elegant way, in order to send XHR requests from my Vue.js client to my Symfony PHP API.
For example i have this GET method endpoint:
/question/list?subjects={idSubject}
It lists Question entity items and optionally, accepts params in order to filter results by them (subjects in this case)
The desired one would be:
/question/list?subjects[]={idSubject}&subjects[]={idSubject}
I'm using Axios for Vue.js to perform XHR requests and i created a main class that implements the methods that i want.
As the get() method doesn't support 'data' property in config object, i implemented it at the same way of a POST call and then i process it in order to build the desired URL.
This is my Ajax.js file:
const ajaxRequest = (config) => {
const token = TokenStorage.get()
config.baseURL = '/ajax'
if (token) {
config.headers = {
'Authorization': 'Bearer ' + token
}
}
return Axios.request(config)
}
const Ajax = {
get: (endpoint, params = null, config = {}) => {
const querystring = require('querystring')
let url = endpoint
if (Array.isArray(params) && params.length) {
url += '?' + params.join('&')
} else if (typeof params === 'object' && params !== null && Object.keys(params).length) {
url += '?' + querystring.stringify(params)
}
config = {
...config,
...{
url: url,
method: 'get'
}
}
return ajaxRequest(config)
},
post: (endpoint, params, config = {}) => {
config = {
...config,
...{
url: endpoint,
method: 'post',
data: params
}
}
return ajaxRequest(config)
}
}
I know that I could pass this data by POST but, in order to follow restful design, i want to keep GET method and optional params can be included in the URL as GET params.
If it were me I'd build a JavaScript array then call JSON.stringify() on it... then URL encode the resultant string and attach it as the sole parameter... to be JSON parsed by your server side handler.
I'm in a similar situation and I couln't find a built in library for this.
the most elegant solution I've found so far is by adding
Array.prototype.encodeURI = function(name) {
prefix = `${name}[]=`;
return prefix + this.map(o => encodeURI(o)).join(`&${prefix}`);
}
now you can use it:
let subjects = ["First Subject", "Second Subject"];
let myquery = subjects.encodeURI("subjects")
console.log(myquery)
// 'subjects[]=First%20Subject&subjects[]=Second%20Subject'
Note:
For empty arrays (e,g: let arr = [];) this method responds with subjects[]=, which php reads as an array with a single empty string (e,g: print_r($_REQUEST["subjects"]) prints Array ( [0] => )).
I couldn't find a standard for sending empty arrays url encoded and you should handle that somewhere.
Expected query string:
http://fqdn/page?categoryID=1&categoryID=2
Axios get request:
fetchNumbers () {
return axios.get(globalConfig.CATS_URL, {
params: {
...(this.category ? { categoryId: this.category } : {})
}
})
.then((resp) => {
// console.log(resp)
})
.catch((err) => {
console.log(err)
})
}
As you can see, it works perfectly with just 1 value for 1 parameter, but if i wanted to make multiple values - it doesn't work, i've tried to use an array:
...(this.category ? { categoryId: [1, 2] } : {})
But it returns this way:
http://fqdn/page?categoryID[]=1&categoryID[]=2
So it just not working. Had a look at this issue: Passing an object with a parameter with multiple values as a query string in a GET using axios
But can't figure out, how he solved this problem.
You can use Axios's paramsSerializer to customize the serialization of parameters in the request.
Note that URLSearchParams serializes array data the way you're expecting:
const searchParams = new URLSearchParams();
searchParams.append('foo', 1);
searchParams.append('foo', 2);
console.log(searchParams.toString()); // foo=1&foo=2
So you could use that class in paramsSerializer as follows:
// my-axios.js
export default axios.create({
paramsSerializer(params) {
const searchParams = new URLSearchParams();
for (const key of Object.keys(params)) {
const param = params[key];
if (Array.isArray(param)) {
for (const p of param) {
searchParams.append(key, p);
}
} else {
searchParams.append(key, param);
}
}
return searchParams.toString();
}
});
// Foo.vue
import axios from './my-axios.js';
export default {
methods: {
async send() {
const { data } = await axios({
url: '//httpbin.org/get',
params: {
categoryId: [1, 2, 3]
}
});
// ...
}
}
}
demo
This is not an axios related issue. It depends on whether your backend service is able to understand query params in this fashion(seems to be framework dependent). From your question, I think it is not working when queryParams like following are sent
?categoryID[]=1&categoryID[]=2
and it expects
?categoryID = 1,2
What you can do is transform array to such string before passing it to params in axios. Update the following piece in your code and it should solve your problem.
...(this.category ? { categoryId: this.category.join(',') } : {})
Take a look at following thread
How to pass an array within a query string?
I'm trying to retrieve data from my service function, but am running into issues. My LandingPage component code, shown below, sends a keystroke to my service function, which then returns an object full of data.
But I cannot get the service object to return to my LandingPage. Here is how I create my service:
task.service.ts
addKey(keystroke) {
const query = "https://api.themoviedb.org/3/search/tv?api_key=";
fetch(query + key + '&language=en-US&query=' + keystroke)
.then((show) => {
show.json().then((obj) => {
// grab the items we want from the response
let resultItems = obj.results.map((show, index) => {
return {
id: show.id,
poster: show.poster_path,
rating: show.vote_average,
backdrop: show.backdrop_path,
};
});
// return our newly formed object
return { data: resultItems }
});
});
}
Here is where I am trying to receive the service data, in my:
landingpage.component.ts
getKey(keystroke) {
this.TaskService.addKey(keystroke)
.subscribe(res => {
this.shows = res.data; // trying to receive service info here
});
}
When I try to build, I receive the following error in my LandingPage component:
Property 'subscribe' does not exist on type 'void'.
I've tried using map instead of subscribe, but it returns a similar error.
How can I send the object result from my service, to my component?
It looks like you're missing a return in your service method, I've also changed to using http from our discussion in the comments:
addKey(keystroke): Observable<any> {
const query = "https://api.themoviedb.org/3/search/tv?api_key=";
return this.http.get(query + key + '&language=en-US&query=' + keystroke)
.map(show => {
show.json().then((obj) => {
// grab the items we want from the response
let resultItems = obj.results.map((show, index) => {
return {
id: show.id,
poster: show.poster_path,
rating: show.vote_average,
backdrop: show.backdrop_path,
};
});
// return our newly formed object
return { data: resultItems }
});
});
}
If you really want to use fetch you can if you:
Set the method return signature to Promise<any>
Use then instead of map in the service
Use then instead of subscribe in the component