Problems with JS Interop when compiled to javascript - dart

I'm using Parse.com as my server solution. I'm loading their framework.js in my dart.html header section.
First of all, everything(CRUD) works great running in Dartium.
Now my goal is to make it work compiled to javascript as well.
First thing I need to do is make login work. The Parse JS for initialization and logging in is as follow:
Parse.initialize("appid", "appkey");
Parse.User.logIn("myname", "mypass", {
success: function(user) {
// Do stuff after successful login.
},
error: function(user, error) {
// The login failed. Check error to see why.
}
});
And here is my updated attempt in Dart. I'm not running with the minified option.
import 'dart:html';
import 'package:web_ui/web_ui.dart';
import 'package:js/js.dart' as js;
void main() {
js.context.Parse.initialize("appid", "appkey");
js.context.Parse.User.logIn("myname","mypass", js.map({
"success": new js.Callback.once((user){
print("success");
}),
"error": new js.Callback.once((user, error){
print("error");
}),
}));
}
It's working great in Dartium and prints "success".
When compiled to javascript I get this error in Safari: JSON.stringify cannot serialize cyclic structures.
The full error in Google Chrome console looks like this:
Uncaught TypeError: Converting circular structure to JSON js.dart:1043
$.Proxy__forward js.dart:1043
$$.Proxy.noSuchMethod$1 js.dart:1033 (anonymous function)
$.main tabort.dart:21
$.main0 tabort.html_bootstrap.dart:8
$$._IsolateContext.eval$1 isolate_helper.dart:265
$.startRootIsolate isolate_helper.dart:89 (anonymous function) tabort.html_bootstrap.dart.js:13949
Help, or pointing me in the right direction would be very appreciated!
EDIT: Downloaded the latest continuous build: 0.1.2_r22610. Now everything works!

The Dart code corresponding to this JS code :
Parse.User.logIn("myname", "mypass", {
success: function(user) {
// Do stuff after successful login.
},
error: function(user, error) {
// The login failed. Check error to see why.
}
});
is :
js.context.Parse.User.logIn("myname", "mypass", js.map({
'success': new js.Callback.once((user) {
// Do stuff after successful login.
}),
'error': new js.Callback.once((user, error) {
// The login failed. Check error to see why.
})
}));
If you compile your Dart code to JS don't use the --minify option because of issue 9283.
EDIT : Your problem ( JSON.stringify cannot serialize cyclic structures ) should disappear starting from r22598 (see https://groups.google.com/a/dartlang.org/d/msg/misc/zZ8Sx5rojis/UddCmmnaYTkJ)

Related

Using Stripe Terminal iOS SDK with Nativescript

I'm attempting to use the Stripe Terminal SDK in the Nativescript plugin seed and test it in the demo-angular app. I'm able to initialize the SDK by setting the connection token provider. When the SDK calls the provider's fetchConnectionToken method, the app crashes with no terminal output when the method calls the SDK-supplied completion handler. Debugging in XCode shows _EXC_BAD_ACCESS code=2.
Relevant code:
iOSFetchConnectionToken(completion: (p1: string, p2: NSError) => void) {
/* No crash if the following two lines are uncommented */
// completion(hardCodedTokenSecret, nullError);
// return;
Http.request({
url: DemoSharedStripeterminalBasic.serverAddress,
method: 'POST',
headers: {
"Content-Type": "application/json",
"Stripe-Public-Key": this.stripeTestKey
},
content: JSON.stringify({
connectedAccountId: this.connectedAccountId
})
}).then(response => {
const result = response.content?.toJSON();
secret = result.secret;
completion(secret, null); // App crashes with no output
})
}
The above function is assigned to the ConnectionTokenProvider's fetchConnectionToken method. I'm able to call the completion handler successfully before the HTTP request (using hardcoded or null values – see the commented lines at the top), but the crash occurs when I invoke the completion handler in the "then" block of the request, using either the returned value from my API server or a hardcoded/null value. Logging out the completion function gives "function () { [native code] }" which indicates that it's properly accessible in memory. I can't figure out where the bad access is coming from or why it's only happening inside the "then" block.
In the sample above, I'm using Nativescript's built in HTTP module, but I've also tried with JS fetch and have the same issue. I've also tried rewriting using async/await with no luck. My API server correctly returns a valid token (I successfully used the same one for the hard-coded token secret), so I know that isn't the issue either. Any help is hugely appreciated, thanks!

Firebase realtime database once method doesn't work in web extensions

i'm using Firebase API to anonymously login and get data from Tampermonkey extension. Works as charm in Chrome but doesn't work in Firefox at all.
firebase.auth().signInAnonymously().catch(function(error) {
console.log("login error: "+ error);
});
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
firebase.database().ref().once("value").then(function(snapshot) {
debugger; // never gets here
GM_setValue("lastUpdate", new Date());
GM_setValue("lastState", snapshot.val());
}).catch(function(error) {
debugger; // never gets here
console.log("error reading DB: " + error);
});
}
});
it never comes to debugger in Firefox. No errors in console at all. what could be a reason? GM_xmlhttprequest instead works more or less in both, but i need auth as well so wanted to use official API.
thank you
UPDATE: after recent Chrome update it doesn't work there as well. Silently dies somewhere...
it turns that there is a value in localStorage that preventing everything from working. code below at application init solves issue.
if (localStorage) { // fix for API
localStorage.removeItem("firebase:previous_websocket_failure");
}
something sets it to true and nobody is cleaning it. there are issues about it since 2017 on github about this, seems not resolved yet.

How to populate Adal8Service 's configOptions using config settings in Angular 7 and load when the application loads

I am using import { Adal8Service, Adal8HTTPService } from 'adal-angular8'; for Azure authentication. I am using the below in app.module.ts:
export function appInit(appConfigService: AppInitService) {
return (): any => {
appConfigService.getApplicationConfig().subscribe((res) =>{
sessionStorage.setItem("appConfig",JSON.stringify(res));
timeout(500);
});
}
}
my getApplicationConfig() is below:
public getApplicationConfig() {
return this.http.get('assets/config.json');}
and in the providers [] the below:
AuthenticationService,
AppInitService,
{
provide: APP_INITIALIZER,
useFactory: appInit,
deps: [AppInitService],
multi: true
},
Adal8Service,
{ provide: Adal8HTTPService,
useFactory: Adal8HTTPService.factory,
deps: [HttpClient, Adal8Service],
multi: true
},
The here is the appInit function does not block (even removing the timeout()) the application loading and proceeds to to the
this.adalService.init(this.adalConfig);
this.adalService.handleWindowCallback();
(where this.adalConfig = sessionStorage.getItem("appConfig")).
If I refresh the page, then I am getting redirected to the Azure Ad login page properly or if I am hardcoding the configOptions of the this.adalService.init("HARDOCDE all values") then it works fine. How do I make the application block the configuration. I am storing the config values under /assets/config.json. I am not sure what I am doing wrong here. I did try reading the "json" file, but again I have to change it before proceeding to production. How do I make the application wait, there are also other config values for the application stored in the /assets/config.json file. Is the way I use the APP_INITIALIZER correct? Please point me to right direction.
The problem is not related to ADAL but related to how asynchronous functions works in javascript.
In order to block the execution of the function, you can either write down a function which waits till the response is returned by the http request or you can use library like waitfor-ES6 which can help you do that.
Change needs to be done at
export function appInit(appConfigService: AppInitService) {
return (): any => {
response = yield wait.for(appConfigService.getApplicationConfig);
sessionStorage.setItem("appConfig",JSON.stringify(response));
}
}
Please note this is not exact change but the direction of the change that you will need to perform. Hope this helps.

Parse-server Cloud Code Error 141 Invalid Function

I am running parse-server on Heroku, I am working on implementing a custom cloud code function, however every implementation returns invalid function code: 141, Version:1.12.0
I have successfully gotten the "hello" function to work, including 1 change I made to it:
Parse.Cloud.define('hello', function(req, res) {
console.log("received.........");
res.success('Hi');
});
The custom function I am trying to get working is a simple query to my database:
Parse.Cloud.define("titleQuery", function(request, response) {
var query = new Parse.Query("StudentNotes");
query.equalTo("title", request.params.title);
query.find({
success: function(results) {
console.log("received........." + results);
response.success(results);
},
error: function() {
console.log("received........." + error);
response.error("title lookup failed");
}
});
});
When I run this on iOS with the following code:
PFCloud.callFunctionInBackground("titleQuery", withParameters: ["title": "testTitle"]) {
(response: AnyObject ? , error : NSError ? ) - > Void in
let hello = response // as? String
print(hello)
}
I am querying my database in class "StudentNotes" for object title with the name "testTitle", I know for a fact that that object exists, however due to it throwing error 141 I do not receive anything. Any help would be greatly appreciated.
EDIT2: I have gotten custom cloud functions to work, however I cannot get any queries to my database to work. Can anyone post a confirmed working query that returns an object? Perhaps from the _User table so that I can copy/paste and ensure that my cloud code can access my database?
My process:
I edit the Main.js file and add in my cloud function.
Then i commit & push (successfully)
finally i restart my Heroku server
Then i still get an error 141 invalid function return
I have successfully solved this problem and gotten regular queries to work. The problem was in my Heroku config vars in the dashboard. My server URL was invalid, never changed from the default of "http://yourappname.com/parse/" I have to manually enter "yourappname".

Grails Events Push plugin not getting a response from server event

I have been trying to get the grails events push plugin to work but cant seem to get response data from the server when the savedToDo event is called. I can see the logs in my console for the data coming to the server and executing the service code, but the client doesnt seem to be getting back a response. My code is as follows :
MyService.groovy
package eventspush
import grails.converters.JSON
import grails.events.*
class MyService {
//will receive client events from 'saveTodo' topic
#Listener(namespace='browser')
def saveTodo(Map data){
log.info(data)
data.moreData = "There we go...."
event('savedTodo', data) // will trigger registered browsers on 'savedTodo' topic
}
}
conf/MyEvents.groovy
events = {
"savedTodo" browser: true, browserFilter: { message, request ->
return true
}
}
index.gsp
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<r:require modules="grailsEvents"/>
<meta name='layout' content='main'/>
<r:script>
$(document).ready(function () {
/*
Register a grailsEvents handler for this window, constructor can take a root URL,
a path to event-bus servlet and options. There are sensible defaults for each argument
*/
window.grailsEvents = new grails.Events("${createLink(uri: '')}", {logLevel:"debug", transport:'websocket'});
var data = new Object();
data.name="some name"
grailsEvents.send('saveTodo', data); //will send data to server topic 'saveTodo'
grailsEvents.on('savedTodo', function (data) {
console.log(data)
}, {});
});
</r:script>
</head>
My problem is that I am not seeing any data being logged in the console. Does anybody have any idea what I am doing wrong?
Edit, I have worked out what was wrong and I have updated the MyEvents.groovy accordingly, the above code is now working
It seems that you have added the 'savedTodo' mapping to the PushEvents.groovy file within the Plugin directory. This is wrong!
You should add your own *Events.groovy file within the conf folder of your own project and leave the PushEvents.groovy file of the plugin untouched!
The other code looks fine so far ;)
There's a typo within your JavaScript section in index.gsp:
it reads:
grailsEvents.send('saveTodo', data);
when it should be:
grailsEvents.send('savedTodo', data);
you omitted the "d" ... ;)
So I found out what what was causing the data not being pushed to the client.
I edited the line in MyService.groovy from being
event('savedTodo', data)
to
event(topic:'savedTodo', data:data)
It is now working as expected

Resources