unclear error from dart2js checked mode - dart

My original error was An attempt was made to use an object that is not, or is no longer, usable. After dart2js runs with the default settings it's pretty difficult to read and I was having trouble debugging the output, so I added these options to my pubspec.yaml:
- $dart2js:
checked: true
sourceMaps: true
verbose: true
minify: false
I was expecting something to break, but I was hoping the error message would be clear enough that I could work it out, but I understand the error I'm getting.
The new error I'm getting is:
Error:
dart<.wrapException()
dart<._rootHandleUncaughtError_closure.call$0()
dart<._microtaskLoop()
dart<._startMicrotaskLoop<()
dart<._AsyncRun__initializeScheduleImmediate_internalCallback.call$1<()
dart<.invokeClosure_closure0.call$0()
dart<._IsolateContext.eval$1()
dart<._callInIsolate()
dart<.invokeClosure<()
dart<.convertDartClosureToJS/$function</<()
It looks like dart is having some trouble converting a closure to a js function. I'd have thought this would be done when dart2js is run and not while the application is running in the browser.
My code doesn't have any explicit closures, but I do use async await. Am I right in assuming that those would be converted into closures?
Just in case it's relevant, I'm also using Angular2.
Update
It appears that my problems are being caused by my use of the HttpRequest.request() from dart:html.
HttpRequest res = await HttpRequest.request( "${API_URL}/login",
method : "POST",
responseType: "json",
mimeType : "application/json",
sendData : JSON.encode( req_data ) );
print( res.status );
If I remove checked mode and build this is giving me the An attempt was made to use an object that is not, or is no longer, usable error.

The API is better, more intuitive.
For example your request :
var client = new BrowserClient();
var response = await client.post("${API_URL}/login",
body: JSON.encode( req_data ));
var data = JSON.decode(response.body);
client.close();
And you could probably see in the parameters if you want more precision in the way you want to define your request.

It seems that I have fixed the problem by changing my use of the HttpRequest class.
From:
HttpRequest res = await HttpRequest.request( "${API_URL}/login",
method : "POST",
responseType: "json",
mimeType : "application/json",
sendData : JSON.encode( req_data ) );
print( res.status );
To:
HttpRequest res = new HttpRequest()
..open( "POST", "${API_URL}/login" );
req
..onLoadEnd.listen( ( ProgressEvent e ) {
print( res.status );
})
..send( JSON.encode( req_data ) );
I'm not sure what the actual problem was, but this way I don't get either the InvalidStateError: An attempt was made to use an object that is not, or is no longer, usable or the longer dart error:
Error:
dart<.wrapException()
dart<._rootHandleUncaughtError_closure.call$0()
dart<._microtaskLoop()
dart<._startMicrotaskLoop<()
dart<._AsyncRun__initializeScheduleImmediate_internalCallback.call$1<()
dart<.invokeClosure_closure0.call$0()
dart<._IsolateContext.eval$1()
dart<._callInIsolate()
dart<.invokeClosure<()
dart<.convertDartClosureToJS/$function</<()
My guess is that dart2js is hving some trouble with async await "implicit" closures and is much happier when I use an "explicit here's a function that closes over it's environment" closure.
Thanks to Günter Zöchbauer for the help.

You should use http package instead
https://pub.dartlang.org/packages/http

Related

Zapier - Invalid API Response

I'm integrating a CRM with Facebook lead Ads using Zapier, and I can create a lead in Facebook and create it in the CRM without any issues.
After a successful post (i.e. successfully creating the lead), I'm curious what I should be returning, I would have thought
return Ok();
would have been enough. Instead, I get an error message saying:
- Got a non-object result, expected an object from create ()
What happened (You are seeing this because you are an admin):
Executing creates.ZapLead.operation.perform with bundle
Invalid API Response:
- Got a non-object result, expected an object from create ()
What should I be returning?
Code which makes the post is:
perform: (z, bundle) => {
const promise = z.request({
url: 'https://{{bundle.authData.subdomain}}.ngrok.io/api/zapier/create/lead/' + bundle.inputData.lead_type + '/' + bundle.inputData.core_customerTypeId,
method: 'POST',
body: JSON.stringify({
fields: bundle.inputData
}),
headers: {
'content-type': 'application/json'
}
});
// return promise.then((response) => JSON.parse(response.content));
return promise.then((response) => {
if (response.status != 200) {
throw new Error(`Unexpected status code ${response.status}`);
}
});
Any ideas?
Thanks,
David here, from the Zapier Platform team.
While your answer is technically correct, I wanted to add some context about the error and why your solution works.
Zapier expects a javascript object (basically anything valid and wrapped in {}) to come out of a create function. That's why JSON.parse(response.content) works, it's returning whatever the server said. Your code throws an error if it's not a 200, but doesn't return anything if it is a 200. Since undefined is not of type Object, the error you're seeing is thrown.
While {"Success":"Success","Attempt":null,"Id":null,"RequestId":null} is totally a valid response (it's an object!), it's more useful for the end-user to return data about the new lead that was created. That way, it can be used downstream for other actions.
​Let me know if you've got any other questions!
As a side note, we're very open to how to make that error message more clear; it's one devs struggle with a lot.
I think I found it. Looks like I need to return this if successful:
{"Success":"Success","Attempt":null,"Id":null,"RequestId":null}

concatenate variable in URL.React Native

I am unable to concatenate state in URL. Have searched but I could not find the solution, and i'm a beginner sorry for asking such a basic question. State has the value before it is sent as a parameter in URL(i have seen it in console), API returns the expected result if I hard code the value, but if a state or even a variable is passed as a parameter it returns error: "NO records found". What am I doing wrong?
this.state.secid = this.props.navigation.state.params.secid
console.log(this.state.secid)
this.state.classid = this.props.navigation.state.params.clasid
console.log(this.state.classid)
// Sending Request
fetch('exampleapi/parameter?
class=${this.state.classid}&section=${this.state.secid}',{
headers: {
'Content-Type':'application/json',
'credentials': 'same-origin',
'Accept': 'application/json',
'Authorization': 'Bearer ' + tokenval
}
})
.then((response) => response.json())
.then((responseJson) => {
this.setState({ allstudents : responseJson })
console.log(this.state.allstudents)
})
You need to make following changes in your code
var url = 'exampleapi/parameter?class='+this.state.classid+'&section='this.state.secid;
fetch(url,{
headers: {
'Content-Type':'application/json',
'credentials': 'same-origin',
'Accept': 'application/json',
'Authorization': 'Bearer ' + tokenval
}
})
Concatenation in react native is done by (+) operator. As URL also a string.
Hope it works for you.
I solved this issue by using backtick notation. Replacing ' '(single quote) in URL by ``(back ticks).
If anybody wants to read more about backtick notation this is an amazing answer : What is the usage of the backtick symbol (`) in JavaScript?
From what I can see in the code added the string concatenation is not done correctly.
It should be done as explained below:
this.state.secid = this.props.navigation.state.params.secid
this.state.classid = this.props.navigation.state.params.clasid
const requestURL = `exampleapi/parameterclass=${this.state.classid}&section=${this.state.secid}`
Then, I would recommend to log and check if you are getting the URL as expected. Also I would suggest to stick to do this es6 way rather than using + for concatenation (As using + is more error prone, you might miss a space place where required - In your case the place you are setting Authorization header ).
Moreover why not use the good stuff when its supported out of the box by react native
Some references:
https://developers.google.com/web/updates/2015/01/ES6-Template-Strings#string_substitution
https://facebook.github.io/react-native/docs/javascript-environment.html
(search for text Template Literals in the page).

"message" : "Internal server error" issue with Lambda/API Gateway and iOS

I've set up a lambda function and created some GET and POST methods inside the API Gateway which seem to work fine when testing them inside the web application.
I am then trying to call the functions inside an iOS application which is set up using the mobile hub. The functions also work inside the testing facility via the mobile hub perfectly fine, however when I actually test the functions inside the app I get:
"message" : "Internal server error"
I know the error is not much to work from, but I can't figure out a way to get a more detailed error description.
Any ideas?
This may happen because your Lambda function is not set to return a HTTP status code.
Changing from
exports.handler = (event, context, callback) => {
callback(null, 'Hello from Lambda');
};
to
exports.handler = (event, context, callback) => {
callback(null, { statusCode: 200, body: 'Hello from Lambda' });
};
Should fix the issue.
The JSON.stringify() solved my issue. The response.body needs to be in String format and not as JSON. I hope this helps.
exports.sendRes = (body, status = 200) => {
var response = {
statusCode: status,
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(body)
};
return response;
};
I had the same issue with the following code:
exports.handler = async event => {
console.log("hello world");
return {
statusCode: 200,
body: event
};
};
To fix all I had to do was JSON.stringify() the body.
exports.handler = async event => {
console.log("hello world");
return {
statusCode: 200,
body: JSON.stringify(event), // <-- here
};
};
I had this problem until I click in "Deploy API" under the "Actions" button.
The other possible reason could be the payload/request/response limits on API Gateway (10MB) and/or Lambda (6MB)
None of the above answers worked for me. I was having a permission issue. Below is how I solved it.
Context
This is my lambda function:
exports.handler = function(event, context, callback) {
callback(null, {
statusCode: '200',
body: JSON.stringify({ 'message': 'hello world' }),
headers: {
'Content-Type': 'application/json',
},
});
};
I used terraform to provision api gateway and lambda. I used the example code provided by this blog post.
Diagnosis
In the lambda console I ran a test event on my lambda. As my lambda was super basic I used the hello world test template, named, and saved it. The test return success.
I checked cloudwatch logs, but couldn't find anything of use. I'm new to AWS so wasn't sure if I had to set anything up.
In the api gateway console I ran a test event. I just added Content-Type:application/json to the headers of the event and ran the test. For whatever weird reason the test results returned on the right side of the browser so had to scroll to the right to see them.
I got this result: Execution failed due to configuration error: Invalid permissions on Lambda function
SOLUTION
I checked the basic terraform example for api gateway and lambda integration here and noticed I was missing the aws_lambda_permission resource. This is needed to give permission to api gateway to invoke the lambda function.
For those that aren't using terraform here is a link to the aws docs on how to create the appropriate permissions.
please try to
Give execute lambda permission API Gateway
tick checkbox : Use Lambda Proxy integration
Handle null pointer for query string, headers & body.
I solved the issue by adding "isBase64Encoded": False/True to my lambda response
results = {
"statusCode": 200,
"headers": {"Content-Type": "application/json"},
"body": json.dumps(res),
"isBase64Encoded": False
}
In my case, the issue resolved while adding the integration Response and redeploying API

Async API call error

I'm currently trying to call the twitter API using meteor and so far i got this:
updateTotalFoll:function(){
var Twit = Meteor.npmRequire('twit');
var T = new Twit({
consumer_key: 'AWzYAlWFRh9zsownZMg3',
consumer_secret: 'aYpL3zMPfqRgtX1usPQpEREEXVNPfNYna9FiIwTeDYR',
access_token: '4175010201-TEp9qNKO4mvjkj0GMjJFZIbGPYaVv4',
access_token_secret: 'EPpcJyN27E4PvhJpYaTHflNFOv3DuR05kTP2j'
});
var Id2=RandomCenas.findOne({api:"twitter"})._id;
T.get('statuses/user_timeline', { screen_name: 'jeknowledge' }, function (err, data, response){
//console.log(data[0].user.followers_count);
RandomCenas.update(Id2,{$set:{totalFoll:data[0].user.followers_count}});
});
}
with "RandomCenas" being a MongoDB.
What i'm trying to do is updating this collection with the info from the call , but i get this error
Error: Meteor code must always run within a Fiber.
Try wrapping callbacks that you pass to non-Meteor libraries with Meteor.bindEnvironment.
I've searched the web for a way to counter this , but i cant seem to apply the solutions that i came across with.
Any help with how i can deal with this?
try it like that
T.get('statuses/user_timeline', { screen_name: 'jeknowledge' }, Meteor.bindEnvironment(function (err, data, response) {
//console.log(data[0].user.followers_count);
RandomCenas.update(Id2,{$set:{totalFoll:data[0].user.followers_count}});
}));
the reason this is happening is because callback function which you pass it's happening outside the current Meteor's Fiber check the answer Error: Meteor code must always run within a Fiber

Polymer <core-xhr> - no POST params sent

I'm desperately trying to send data via POST to a express.js application. The express.js app works fine but for whatever reason the POST data isn't sent to the server properly:
var xhrConfig = {
url: "http://localhost:3000/test",
body: {"foo": "bar"},
// body: JSON.stringify({"foo": "bar"}),
// body: 'foo=bar',
method: "POST"
};
document.createElement('core-xhr').request(xhrConfig);
My express.js console.log(req.body) output is always {}. No matter if body is sent stringified or raw or JSON. I also tried params instead of body just to make sure.
I tried the same in jQuery to exclude the possibility of having a bug in my express.js route but $.ajax({url: 'http://localhost:3000/test', data: {foo: 'bar'}, type: 'POST'}); works perfectly fine.
So what's the reason that req,body is always empty? Any ideas?
//edit:
body: "foo=bar",
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
This one works now but is there a way to be able to use body: {"foo": "bar"} instead of converting it to foo=bar first?
As far as I know, core-xhr is a low level element, and the body object on it's conf doesn't accept a JS object but the string body you want to use.
For the use you describe, you could try core-ajax, a higher level element that can be configured with an object. Doc on core-ajax: https://www.polymer-project.org/docs/elements/core-elements.html#core-ajax.
<core-ajax
auto
url="http://localhost:3000/test"
body='{"foo": "bar"}'
handleAs="json"
method: "POST"
on-core-response="{{handleResponse}}"></core-ajax>
Hope it helps. If you need a more detailed example, don't hesitate to ask.
Looks like express looks at the Content-Type header to determine what type of body it has, below works for me.
this.$.xhr.request({
url: "/my/url",
method: "POST",
headers:{
"Content-Type":"application/json"
},
body: JSON.stringify(survey),
callback: function(response){
console.log(response);
}
});
I had this problem as well on Polymer. This problem is very frustrating because there isn't much documentation on Polymer on core-xhr.
As you have already answered the first question yourself, I'll answer the latter: yes/no. If you look at the source of <core-xhr>, it just feeds the params straight to xhr.send(params). however, there is a method inside of called toQueryString, which does what you want to do.
toQueryString: function(params) {
var r = [];
for (var n in params) {
var v = params[n];
n = encodeURIComponent(n);
r.push(v == null ? n : (n + '=' + encodeURIComponent(v)));
}
return r.join('&');
}

Resources