Im using Angular + ts.
My request looks like:
getOrders(this.value.id, null, null).subscribe((s) => {
this.ordersArray = s
})
For some reason. null is converted to "null" on the server, what could be the reason for this?
backend console
Started GET "/admin/api/as_supplier/orders.json?start=null&end=null" for ::1 at 2022-04-19 11:01:32 +0300
Processing by Admin::Api::AsSupplier::OrdersController#index as JSON
Parameters: {"start"=>"null", "end"=>"null"}
Completed 500 Internal Server Error in 30ms (ActiveRecord: 0.0ms)
Or is the problem not on the frontend, but on the backend?
upd:
public getOrders(supplierId?: any, start?: any, end?: any): Observable<IOrders> {
return this.http
.get<IOrders>(`${environment.apiUrl}/admin/api/as_supplier/orders.json`, {
params: {
start,
end
}
})
.pipe(tap(response => this.orders = response))
}
you should do something like this:
let params = new HttpParams();
if (start !== null && start !== undefined) {
params = params.set('start', start);
}
if (end !== null && end !== undefined) {
params = params.set('end', end);
}
return this.http.get<IOrders(`${environment.apiUrl}/admin/api/as_supplier/orders.json`, {params})
#Alex i think the problem in your server side, try to parse params before you use it in the rest of your code in API
Related
I am experiencing the following error: NSwagStudio generates a typescript client which is trying to deserializing json when api return type is plain string.
I am using .netCore 2.2 and NSwagStudio 13.16.1
The client generated is:
if (status === 400) {
return blobToText(responseBlob).pipe(_observableMergeMap(_responseText => {
let result400: any = null;
result400 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as string;
return throwException("A server side error occurred.", status, _responseText, _headers, result400);
}));
while the API has the following decorator:
[ProducesResponseType(typeof(string),StatusCodes.Status400BadRequest)]
As you can see, the client is trying to parse the _responseText, which causes the error. The _responseText is a plain string.
How can i solve this problem?
I think it's a Front End problem. Please, don't minimize.
if (status === 400) {
return blobToText(responseBlob).pipe(_observableMergeMap(_responseText => {
let result400: any = null;
result400 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as string;
return throwException("A server side error occurred.", status, _responseText, _headers,
}));
}
I'm trying to send a GET request to Binance's API, but I don't exactly know how to.
Here is the documentation page: https://github.com/binance-exchange/binance-official-api-docs/blob/master/rest-api.md#account-information-user_data
I have a private apiKey and secretKey.
I can do a general request to Binance, but I cannot get my private data, using my private keys.
First try:
For the GET request in Postman I use this string:
https://api.binance.com/api/v3/account?timestamp=1499827319559&signature=here_I_put_my_secret_key
And I pass as a header as Danny suggested the apiKey.
But I get:
{
"code": -1021,
"msg": "Timestamp for this request is outside of the recvWindow."
}
Thanks.
I solved this correcting the time using javascript in Postman.
Another easy fix is to use the ccxt library : https://github.com/ccxt/ccxt
This might be what you're after, as per the documentation.
https://github.com/binance-exchange/binance-official-api-docs/blob/master/rest-api.md#endpoint-security-type
API-keys are passed into the Rest API via the X-MBX-APIKEY header.
In your Request, add that as the header key and your API Key as the value.
You can try this. This is working for me. Just Replace your API_KEY and SECRET
You need to retrieve serverTime time from https://api.binance.com/api/v3/time and need to use that serverTime to sign the request.
GET : https://api.binance.com/api/v3/account?timestamp={{timestamp}}&signature={{signature}}
Header:
Content-Type:application/json
X-MBX-APIKEY:YOUR_API_KEY
Pre-request Script :
pm.sendRequest('https://api.binance.com/api/v3/time', function (err, res) {
console.log('Timestamp Response: '+res.json().serverTime);
pm.expect(err).to.not.be.ok;
var timestamp = res.json().serverTime;
postman.setEnvironmentVariable('timestamp',timestamp)
postman.setGlobalVariable('timestamp',timestamp)
let paramsObject = {};
const binance_api_secret = 'YOUR_API_SECRET';
const parameters = pm.request.url.query;
parameters.map((param) => {
if (param.key != 'signature' &&
param.key != 'timestamp' &&
!is_empty(param.value) &&
!is_disabled(param.disabled)) {
paramsObject[param.key] = param.value;
}
})
Object.assign(paramsObject, {'timestamp': timestamp});
if (binance_api_secret) {
const queryString = Object.keys(paramsObject).map((key) => {
return `${encodeURIComponent(key)}=${paramsObject[key]}`;
}).join('&');
console.log(queryString);
const signature = CryptoJS.HmacSHA256(queryString, binance_api_secret).toString();
pm.environment.set("signature", signature);
}
function is_disabled(str) {
return str == true;
}
function is_empty(str) {
if (typeof str == 'undefined' ||
!str ||
str.length === 0 ||
str === "" ||
!/[^\s]/.test(str) ||
/^\s*$/.test(str) ||
str.replace(/\s/g,"") === "")
{
return true;
}
else
{
return false;
}
}
}
);
Get the official Postman collections for the Binance API from here:
https://github.com/binance/binance-api-postman
Import the desired collection and environment in Postman, for instance
binance_spot_api_v1.postman_collection.json
and binance_com_spot_api.postman_environment.json
Add your API key to the binance-api-key environment variable and your secret key to the binance-api-secret variable.
CAUTION: Limit what the key can do in Binance key management. Do not use this key for production, only for testing. Create new key for production.
For the signed requests calculate the signature in a Pre-request Script then set the signature environment variable.
Example Pre-request Script:
function resolveQueryString() {
const query = JSON.parse(JSON.stringify(pm.request.url.query))
const keyPairs = []
for (param of query) {
if (param.key === 'signature') continue
if (param.disabled) continue
if (param.value === null) continue
const value = param.value.includes('{{') ? pm.environment.get(param.key) : param.value
keyPairs.push(`${param.key}=${value}`)
}
return keyPairs.join('&')
}
const signature = CryptoJS.HmacSHA256(
resolveQueryString(),
pm.environment.get('binance-api-secret')
).toString(CryptoJS.enc.Hex)
pm.environment.set('signature', signature)
The following Node.js code:
var request = require('request');
var getLibs = function() {
var options = { packages: ['example1', 'example2', 'example3'], os: 'linux', pack_type: 'npm' }
request({url:'http://localhost:3000/package', qs:options},
function (error , response, body) {
if (! error && response.statusCode == 200) {
console.log(body);
} else if (error) {
console.log(error);
} else{
console.log(response.statusCode);
}
});
}();
sends the following http GET request query that is received by like this:
{"packages"=>{"0"=>"example1", "1"=>"example2", "2"=>"example3"}, "os"=>"linux", "pack_type"=>"npm"}
How can I optimize this request to be received like this:
{"packages"=>["example1", "example2", "example3"], "os"=>"linux", "pack_type"=>"npm"}
Note. The REST API is built in Ruby on Rails
If the array need to be received as it is, you can set useQuerystring as true:
UPDATE: list key in the following code example has been changed to 'list[]', so that OP's ruby backend can successfully parse the array.
Here is example code:
const request = require('request');
let data = {
'name': 'John',
'list[]': ['XXX', 'YYY', 'ZZZ']
};
request({
url: 'https://requestb.in/1fg1v0i1',
qs: data,
useQuerystring: true
}, function(err, res, body) {
// ...
});
In this way, when the HTTP GET request is sent, the query parameters would be:
?name=John&list[]=XXX&list[]=YYY&list[]=ZZZ
and the list field would be parsed as ['XXX', 'YYY', 'ZZZ']
Without useQuerystring (default value as false), the query parameters would be:
?name=John&list[][0]=XXX&list[][1]=YYY&list[][2]=ZZZ
I finally found a fix. I used 'qs' to stringify 'options' with {arrayFormat : 'brackets'} and then concatinated to url ended with '?' as follows:
var request = require('request');
var qs1 = require('qs');
var getLibs = function() {
var options = qs1.stringify({
packages: ['example1', 'example2', 'example3'],
os: 'linux',
pack_type: 'npm'
},{
arrayFormat : 'brackets'
});
request({url:'http://localhost:3000/package?' + options},
function (error , response, body) {
if (! error && response.statusCode == 200) {
console.log(body);
} else if (error) {
console.log(error);
} else{
console.log(response.statusCode);
}
});
}();
Note: I tried to avoid concatenation to url, but all responses had code 400
This problem can be solved using Request library itself.
Request internally uses qs.stringify. You can pass q option to request which it will use to parse array params.
You don't need to append to url which leaves reader in question why that would have been done.
Reference: https://github.com/request/request#requestoptions-callback
const options = {
method: 'GET',
uri: 'http://localhost:3000/package',
qs: {
packages: ['example1', 'example2', 'example3'],
os: 'linux',
pack_type: 'npm'
},
qsStringifyOptions: {
arrayFormat: 'repeat' // You could use one of indices|brackets|repeat
},
json: true
};
ok this is something that start to show a few weeks ago, I have a parse server running on an ubuntu machine with version 2.3.3, I have a bunch of cloud functions running, nothing fancy just querying some specific Class, all the data in that class is public and all work most of the time just fine. However from time to time, calling a cloud function start to return invalid sessions error 209, even with a user logged or not, super weird, but what is even strange is that when that happens no one else can run the function, and every user start to got the same error.
The only way I can make it work again is restarting the server, also only happens with cloud functions and from the ios app, I saying this cause we have some other part calling functions from php but it seems those are not starting the problem
2017-02-21T01:26:57.676Z - Failed running cloud function partnersv2 for user undefined with:
Input: {"k":"","searchType":"","category":"comida"}
Error: {"code":141,"message":{"code":209,"message":"invalid session token"}}
2017-02-21T01:26:57.669Z - invalid session token
2017-02-21T01:26:55.738Z - ParseError { code: 209, message: 'invalid session token' }
2017-02-21T01:26:55.737Z - Error generating response. ParseError {
code: 141,
message: ParseError { code: 209, message: 'invalid session token' } }
I have no idea why is this happening, also I don't think is related to the legacy session cause this server and the user are new, we start developing this a few months ago is not a ported app from the old service
One thing we are doing a lot is removing from the dashboard sessions at will, cause we are testing and developing, not sure if this could be a reason, but what about when the user is undefined, it shouldn't even try to use session I think, or maybe a user that was actually logged could be the culprit, setting the server to VERBOSE is not telling anything else as well, just the params and the call which it doesn't look weird to me, am looking for someone that maybe can put me in the right direction of maybe how the session work or something, thank you for any help
EDIT 1:
This is the cloud function that is trowing the error
Parse.Cloud.define('partnersv2', function (req, res) {
var searchType = req.params.searchType,
k = req.params.k,
category = req.params.category,
query;
query = new Parse.Query('Partner');
query.addDescending('is_open');
query.equalTo('enabled', true);
query.equalTo('category', category);
query.select(['name', 'phone', 'delivery_eta', 'keys', 'price_range', 'is_new', 'cover', 'recommended', 'open_time', 'min_order', 'delivery_rank', 'logo', 'comingsoon', 'category', 'is_open']);
if (searchType !== '' && searchType !== undefined && k !== '' && k !== undefined) {
if (searchType === 'Tag') {
query.equalTo('tags', k);
} else {
query.equalTo('name', k);
}
}
query.limit(1000);
query.find({
success: function (results) {
if (results.length > 0) {
res.success(results);
} else {
res.error('404 not found');
}
},
error: function (error) {
res.error(error);
}
});
});
and this is a screenshot of the ACL col
Use Master Key
Parse.Cloud.define('partnersv2', function (req, res) {
//var token = req.user.getSessionToken() // getSession Token return r: (yourkey);
var searchType = req.params.searchType,
k = req.params.k,
category = req.params.category,
query;
query = new Parse.Query('Partner');
query.addDescending('is_open');
query.equalTo('enabled', true);
query.equalTo('category', category);
query.select(['name', 'phone', 'delivery_eta', 'keys', 'price_range', 'is_new', 'cover', 'recommended', 'open_time', 'min_order', 'delivery_rank', 'logo', 'comingsoon', 'category', 'is_open']);
if (searchType !== '' && searchType !== undefined && k !== '' && k !== undefined) {
if (searchType === 'Tag') {
query.equalTo('tags', k);
} else {
query.equalTo('name', k);
}
}
query.limit(1000);
query.find({
useMasterKey: true, // sessionToken: token
success: function (results) {
if (results.length > 0) {
res.success(results);
} else {
res.error('404 not found');
}
},
error: function (error) {
res.error(error);
}
});
});
I am trying to make a POST request.
Here my code:
var myModel = new MydModel({
content: "ciao"
});
console.log(myModel.get("content")); // "ciao"
myModel.save();
If I look to the network activity it looks like this:
The response part {id:0, content:"", ……}
In the header part: Request Payload {"content":"ciao"}
Here my model:
define([], function () {
var MyModel = Backbone.Model.extend({
url: function url ()
{
return "http://localhost/users";
}
});
return MyModel;
});
Is it my problem or is it in the server part?
send/receive vs request/response
a server receives requests and sends responses
a client sends requests and receives responses
in short
if {id:0, content:"", ……} (the response) is wrong, it's your server
if {"content":"asdasdsa"} (the request) is wrong, it's your client
There is little problem with receiving JSON-payload that "Backbone-client" sends to your Apache-server.
All you need to do is to manually parse JSON-payload from input on the server side ("php://input", for PHP), like this:
if($_SERVER['REQUEST_METHOD'] == 'PUT' || $_SERVER['REQUEST_METHOD'] == 'POST') {
$postStr = file_get_contents("php://input");
//json_decode throws error or returns null if input is invalid json
try {
$json = json_decode($postStr, true);
if(empty($json)) {
throw new Exception("Not valid json");
}
//must not be json, try query str instead
} catch(Errfor $e) {
$postVars = parse_str($postStr);
foreach($postVars as $key=>$data) {
$_POST[$key] = $data;
}
}
}
Full explanation you can find here:
http://colinbookman.com/2014/04/08/php-puts-posts-and-backbone-js/