I think I'm using Redbean 3.3.7 (the all-in-one download from the website), but I can't find a version number in the code.
I am receiving some json encoded data and want to process it with R::graph(), but I'm getting an error.
$json = '{"id": "","title": "Test Article","slug": "test-article","content": "<p>This is a test article</p>"}';
$decoded = json_decode($json, true);
This gives me an array
var_dump($decoded)
array(4) {
["id"]=>
string(0) ""
["title"]=>
string(12) "Test Article"
["slug"]=>
string(12) "test-article"
["content"]=>
string(29) "<p>This is a test article</p>"
}
Also
echo gettype($decoded);
returns "array".
But when I try this:
$bean = R::graph($decoded);
I get a RedBean_Exception_Security error with the message "Expected array but got :string";
rb.php line 9029
What am I doing wrong?
And more importantly, how do I fix it?
Thanks.
According to the documentation "An array has to contain a key named 'type' containing the type of bean it represents". So I just had to add $decoded['type'] = 'table_name' before calling R::graph(). It also works if I add a hidden field named 'type' in the form I submit.
<input type="hidden" name="type" value="table_name" />
Related
I am using a hybrid application with vuejs and ruby on rails, I want to translate the error messages that come to me from the server, for the titles I could easily do them with a method but for the error messages I don't know how to translate them.
these are my errors taken from the server, as you can see the title of the error I managed to translate it, but the message I don't know how to do. For example End date i want to translate the message.
my code to get the errors:
<div v-if="getDataError">
<div v-for="(_errors, key) in getDataError">
<b-alert
v-for="error in _errors"
show
variant="danger"
>
<h2>{{ formatKey(key) }} :</h2>
<li>{{ error }}</li>
</b-alert>
</div>
</div>
my method to translate the title message :
methods: {
formatKey (key) {
return this.$t('vue.' + key.replace('contract_data.', ''))
}
},
As I can see you are getting three type of errors from the server (API response) :
Unprocessable Entity
can't be blank
teammate_contract_end_after_company_contract
Approach : You can assign these errors in to language object like below.
const messages = {
en: {
error: {
'code422Msg': 'Unprocessable Entity',
'requiredFieldMsg': 'can't be blank',
'endDateMsg': 'teammate_contract_end_after_company_contract'
}
}
}
Now, Instead of returning the error text from API, you can return error.code422Msg, error.requiredFieldMsg, error.endDateMsg based on the validations.
And then finally, translate these dot notation strings in template or in script using $t('error.code422Msg'), $t('error.requiredFieldMsg'), $t('error.endDateMsg')
Hope it will work! Thanks
I'm making an API call that returns XML (JSON also available) and the response body will show errors if any. There may be only one error or multiple errors. When the XML (or JSON) is parsed into a hash, the key that holds the errors will be an array when multiple errors are present but will be just a standard key when only one error is present. This makes parsing difficult as I can't seem to come up with one line of code that would fit both cases
The call to the API returns this when one error
<?xml version=\"1.0\" encoding=\"utf-8\"?><response><version>1.0</version><code>6</code><message>Data validation failed</message><errors><error><parameter>rptFilterValue1</parameter><message>Parameter is too small</message></error></errors></response>
And this when multiple errors
<?xml version=\"1.0\" encoding=\"utf-8\"?><response><version>1.0</version><code>6</code><message>Data validation failed</message><errors><error><parameter>rptFilterValue1</parameter><message>Parameter is too small</message></error><error><parameter>rptFilterValue2</parameter><message>Missing required parameter</message></error></errors></response>
I use the following to convert the XML to a Hash
Hash.from_xml(response.body).deep_symbolize_keys
This returns the following hash.
When there is only one error, the hash looks like this
{:response=>{:version=>"1.0", :code=>"6", :message=>"Data validation failed", :errors=>{:error=>{:parameter=>"rptFilterValue1", :message=>"Parameter is too small"}}}}
When there are 2 errors, the hash looks like this
{:response=>{:version=>"1.0", :code=>"6", :message=>"Data validation failed", :errors=>{:error=>[{:parameter=>"rptFilterValue1", :message=>"Parameter is too small"}, {:parameter=>"rptFilterValue2", :message=>"Missing required parameter"}]}}}
When I first tested the API response, I had multiple errors so the way I went about getting the error message was like this
data = Hash.from_xml(response.body).deep_symbolize_keys
if data[:response].has_key?(:errors)
errors = data[:response][:errors][:error].map{|x| "#{x.values[0]} #{x.values[1]}"}
However when there is only one error, the code errors out with undefined method 'values' for parameter
The only actual workaround I found was to test the class of the error key. When Array I use one method for extracting and when Hash I use another method.
if data[:response][:errors][:error].class == Array
errors = data[:response][:errors][:error].map{|x| "#{x.values[0]} #{x.values[1]}"}
else
errors = data[:response][:errors][:error].map{|x| "#{x[1]}"}
end
But I just hate hate hate it. There has to be a way to extract xml/json data from a key that may or may not be an array. The solution may be in the conversion from xml to hash rather than when parsing the actual hash. I couldn't find anything online.
I'll appreciate any help or tip.
If you're using Rails, Array#wrap is available if you can do your .dig first:
single = {:response=>{:version=>"1.0", :code=>"6", :message=>"Data validation failed", :errors=>{:error=>{:parameter=>"rptFilterValue1", :message=>"Parameter is too small"}}}}
Array.wrap(single.dig(:response, :errors, :error))
This returns an Array of size 1:
[
{
:message => "Parameter is too small",
:parameter => "rptFilterValue1"
}
]
For multiples:
multiple = {:response=>{:version=>"1.0", :code=>"6", :message=>"Data validation failed", :errors=>{:error=>[{:parameter=>"rptFilterValue1", :message=>"Parameter is too small"}, {:parameter=>"rptFilterValue2", :message=>"Missing required parameter"}]}}}
Array.wrap(multiple.dig(:response, :errors, :error))
This returns an Array of size 2:
[
{
:message => "Parameter is too small",
:parameter => "rptFilterValue1"
},
{
:message => "Missing required parameter",
:parameter => "rptFilterValue2"
}
]
You can parse XML with Nokogiri and xpath, which returns array even if selector points out single element
errors = Nokogiri::XML(xml_response).xpath('//error')
errors.map { |e| e.children.each_with_object({}) { |x, h| h[x.name] = x.content } }
Your API response with single error gives
=> [{"parameter"=>"rptFilterValue1", "message"=>"Parameter is too small"}]
and API result with multiple errors
=> [{"parameter"=>"rptFilterValue1", "message"=>"Parameter is too small"}, {"parameter"=>"rptFilterValue2", "message"=>"Missing required parameter"}]
If there's no error elements you'll get an empty array.
I perform an update via my OData service like this:
oModel.create('/Carriers', oEntry, null, function () {
oModel.refresh();
sap.m.MessageBox.show("Saved", sap.m.MesESS);
}, function (err) {
var message = $(err.response.body).find('message').first().text();
sap.m.MessageBox.show(message, sap.m.MessageBox.Icon.ERROR);
});
If I get an error message in the response I am unable to display the message text.
I create the error like this:
CALL METHOD lo_message_container->add_message_text_only
EXPORTING
iv_msg_type = 'E'
iv_msg_text = msg_text.
RAISE EXCEPTION TYPE /iwbep/cx_mgw_busi_exception
EXPORTING
message_container = lo_message_container.
ENDIF.
The err.response.body looks like this:
"{"error":{"code":"SY/530","message":{"lang":"en","value":"This
is the error I am trying to show)"},
"innererror":{"transactionid":"B20B61E5143BF10E92CB000C29D28D3A","timestamp":"20150922092421.4230000","Error_Resolution":{"SAP_Transaction":"Run
transaction /IWFND/ERROR_LOG on SAP NW Gateway hub system and search
for entries with the timestamp above for more details","SAP_Note":"See
SAP Note 1797736 for error analysis
(https://service.sap.com/sap/support/notes/1797736)"},"errordetails":[{"code":"","message":"This
is the error I am trying to show
","propertyref":"","severity":"error","target":""},{"code":"/IWBEP/CX_MGW_BUSI_EXCEPTION","message":"","propertyref":"","severity":"error","target":""}]}}}"
I was trying this but it does not work...
var message = $(err.response.body).find('message').first().text();
sap.m.MessageBox.show(message, sap.m.MessageBox.Icon.ERROR);
It looks like your error is mistaking JSON for a DOM object.
jQuery (the $-sign function) is meant to select DOM elements with the tag name, classes or the id.
To find the right key in an JSON structure, you can use normal JavaScript dot- or brackets-notation:
var message = err.response.body.error.message.value;
I wants to send some json parameter from HTML page with text area and I want to send json parameter written in this text area eg format. {"name": "test", "description":"test", "price":100}
But rails consider it as {"{'name' : 'test', 'description' : 'test', 'price' : 100}"=>nil} how do I send json parameter from text area to be readable from rails application.
I think you need to parse that string on server side with JSON.parse
param = '{"name" : "test", "description" : "test", "price" : 100}'
# assume you got the param on server side
json_param = JSON.parse(param)
puts json_param['name']
As you stated in the comment:
You can easily understand from this sample:
<input type='textarea' name='content' value='{"name": "test", "description":"test", "price":100}' id='text_content' />
You just sent a string to Rails in this way.
If you do the submit with a form, you should use different inputs for different params.
If Javascript, maybe jQuery, you can do it with function $.post.
Rails would parse the json for you.
I'm damned if I can make this work. Your help would be appreciated. I have valid access tokens, and can use twitteroauth to post status updates. However: every way I've tried to come at retweets has failed.
$parameters = array('id' => $status_id);
$retweet = $connection->post('statuses/retweet', $parameters);
Gets an error response of "not found." I'm not sure what's not found - the id of the tweet that I'm trying to retweet, or the method I'm calling (statuses/retweet). I'm passing valid ID's through the request (I can find them on Twitter), and so on. Any ideas?
Here's the documentation:
http://dev.twitter.com/doc/post/statuses/retweet/:id
I've also tried:
$parameters = array('id' => $status_id);
$retweet = $connection->post('statuses/retweet/', $parameters);
$parameters = array('id' => $status_id);
$retweet = $connection->post('statuses/retweet/:', $parameters);
and...
$retweet = $connection->post('statuses/retweet/:123456.json');
With either null responses (??) or the same enigmatic "not found."
$retweet = $connection->post('statuses/retweet/123456');
:id is a variable syntax that similar to PHP's $id so you replace it in its entirety with the value.
$parameters is only used when the key value pairs are getting added as URL parameters like ?key=value not in the URL path.
The format is automatically handled by the library so you should not include .json manually.
Another tip on this issue is to reference "id_str" rather than the "id" as the "id" integer is sometimes wrong.