Super expression must either be null or a function - ios

I have written this piece of code to build a simple react native UI
'use strict';
var React = require('react-native');
var styles = React.StyleSheet.create({
text : {
color : 'black',
backgroundColor : 'white',
fontSize : 30,
margin : 80
}
});
class PropertyFinderApp extends React.Component() {
render() {
return React.createElement(React.text,{style : styles.text},"Hello World");
}
}
React.AppRegistry.registerComponent('PropertyFinder',function(){ return PropertyFinderApp});
I am getting error "Super expression must either be null or a function"
I have already tried installing the latest version of react but I am still unable to solve it!

What's causing your error is the React.Component() which should be without the parentheses React.Component. When you fix that you will get another error from the use of lowercase React.text which should be React.Text.

Related

How to get babel to work with new threejs versions

I am having trouble updating threejs to the new es6 class version that they introduced because I am having trouble with babel.
I have the following code where I am extending Object3D
import {
Object3D,
} from "three";
type Props = {
myProp:string
};
export default class MyBox extends Object3D {
constructor(props: Props = {}) {
super();
console.log("HERE");
this.init(props);
console.log("Done");
}
init(props){
// Do stuff
}
Now this works in almost every case just fine, except when I am trying to load it in an ios webview. In that case I drilled down and saw that my code is transpiled to
function e() {
var e,
o = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {};
return e = n.call(this) || this, console.log("HERE"), e.init(o), console.log("DOne"), e
Which on the ios webview throws an error saying:
TypeError: Cannot call a class constructor without |new|
Which to me means since Object3D is a class it cannot be called like the transpiled version wants to.
{
"presets": ["#babel/preset-flow", ["#babel/preset-env",
{
"targets": ">1%"
}], "#babel/react"],
"plugins": [
"#babel/transform-runtime",
"#babel/plugin-syntax-flow",
"#babel/plugin-transform-flow-strip-types",
"#babel/plugin-proposal-class-properties"]
}
I have tried playing with the targets property and other packages, but have had no luck. My understanding is the threejs is not getting transpiled, whereas the rest of my code is.
Edit: I was wrong about the cause, it was actually due to Meteor build systems misdetecting whether this was a legacy case or not
Answer for me ended up being:
import { setMinimumBrowserVersions } from "meteor/modern-browsers";
setMinimumBrowserVersions(
{
"mobileSafariUI/WKWebView": 10,
},
"classes"
);

React Navigation get Param from deep linking not working

I have configured my router like:
const SwitchRouter = createSwitchNavigator(
{
Splash: {
screen: Launch,
path: 'hello/:code',
},
App: HomeStack,
},
{
initialRouteName: 'Splash',
}
);
I'm using a link in Safari, which launches my iOS app and then I should get a parameter from this link in my code.
I tried different with links but I was not able to get any parameter from them. Here is what I've tried:
myApp://hello/123
myApp://hello/?code=123
myApp://hello?code=123
My code which should get this code parementer is in my Launch screen as below:
const code = navigation.getParam('code', 'error');
The code value is always an error, my param here is never found.
Am I missing something here? I've been through all the GitHub and documentation of react-navigation I couldn't find a solution working for me.
I read some people have some issue getting their deep linking params in componentDidMount. Apparently they are not available.
So my code here in charge of getting my parameter 'code' I tried to use it inside componentDidMount/DidUpdate and even in the render but in all cases I can't get my param.
I figured that you cannot pass deeplink params to the first/initial screen.
You have to use a proxy instead:
const SwitchRouter = createSwitchNavigator(
{
CodeScreen: {
Screen: Code,
path: 'code/:code',
}
Splash: {
screen: Launch,
path: 'hello',
},
App: HomeStack,
},
{
initialRouteName: 'Splash',
}
});
class Code extends Component {
constructor(props) {
super(props);
const {navigation} = this.props;
const code = navigation.getParam('code', false);
navigation.navigate('hello', {code});
}
render() {
return (
<View>
</View>
);
}
}
Now you retrieve the 'code' param in your SplashScreen.

Calling a javascript function, which is passed as a parameter from a javascript library

I'm currently trying to implement the fullcalendar javascript library into an angular 2 dart webapp.
I'm having problems porting this javascript code to dart though:
$('#fullCalendar').fullCalendar(
{
events: function(start, end, timezone, callback) {
var generated_events=[
{
title : 'test',
start : '2016-08-08'
}];
callback(generated_events);
},
allDaySlot: false
//More options can go here
});
I've gotten as far as being able to pass a dart function to the events parameter with this code:
context.callMethod(r'$',['#fullCalendar'])
.callMethod('fullCalendar',[new JsObject.jsify({
'events': (start, end, timezone, callback){
print("called!");
List<FullCalendarEvent> generated_events= [
new FullCalendarEvent(title: "test", start: "2016-08-08")
];
try{
callback(generated_events);
}catch(exception,stackTrace){
print("Caught exception!");
print(exception);
print(stackTrace);
}
},
'allDaySlot': false
//more options can go here
})]);
Where the FullCalendarEvent is a simple anoymous class structure:
#JS()
#anonymous
class FullCalendarEvent{
external String get title;
external set title(String v);
external String get start;
external set start(String v);
external factory FullCalendarEvent({
String title,
String start
});
}
However the callback(generated_events); throws this exception:
NoSuchMethodError: method not found: 'call$1' (callback.call$1 is not a function)
Edit:
With the help of Günter's replies I managed to fix the problem. Instead of doing callback(generated_events); I instead use callback.apply([generated_events]); Additionally instead of using
List<FullCalendarEvent> generated_events= [
new FullCalendarEvent(title: "test", start: "2016-08-08")
];
I instead use:
var generated_events = new JsObject.jsify([{'title':'test','start':'2016-08-08'}]);
My working code looks like this:
context.callMethod(r'$',['#fullCalendar'])
.callMethod('fullCalendar',[new JsObject.jsify({
'events': (start, end, timezone, callback){
print("called!");
var generated_events = new JsObject.jsify([{'title':'test','start':'2016-08-08'}]);
try{
callback.apply([generated_events]);
}catch(exception,stackTrace){
print("Caught exception!");
print(exception);
print(stackTrace);
}
},
'allDaySlot': false
//more options can go here
})]);
A JS function should be callable with
callback.apply([gen‌​erated_events])

PropType validation does not show warning in console

I am using React with ASP.NET and am trying to implement propType validation. But I don't receive any warnings even though the props I am passing to my component are clearly invalid:
var LoginBox = React.createClass({
propTypes: {
// the 'url' prop is not given and should result in a warning
url: React.PropTypes.string.isRequired,
// given 'modalId' is a a string and should result in a warning as well
modalId: React.PropTypes.bool
},
// some other functions ...
render() { ... }
)};
ReactDOM.render(
<LoginBox modalId="forgotModal" loginUrl="/user/login" />,
document.getElementById('content')
);
Am I not using the validation correctly?
You are using production version of react(.min.js), propTypes warning are disabled there.

Splitting Yeoman prompts into multiple separate groups

how would one split a yeoman prompt into parts?
I have a rather extended prompt that i'd like to split into parts with a title for each part.
CSS
- prompt1
HTML
-prompt 2
Something like this:
prompt1: function(){
var done = this.async();
condole.log('title 1');
var prompts = [{
name: 'prompt1',
message: 'Prompt 1:',
}]
},
prompt2: function(){
var done = this.async();
condole.log('title 2');
var prompts = [{
name: 'prompt2',
message: 'Prompt 2:',
}]
},
Thanks!
Update as #Deimyts notes in the comments, the original code stopped working. This is due to API changes in Inquirer.JS documented here.
The base API interface is now inquirer.prompt(questions).then(). There's no more callback function.
Any async question functions is taking a promise as return value instead of requiring this.async().
In a nutshell, instead of using the old var done = this.async() API and resolving the prompt inside the callback with done() just return a promise from the prompting functions (see docs).
prompt1: function() {
this.log("HTML")
return this.prompt([
// configure prompts as before
]).then(function (answers) {
// callback body as before, but no more calling done()
}.bind(this));
},
For more details see #Deimyts answer below.
Yeoman uses a run loop with certain predefined priorities that you can use to put your actions into. As mentioned in the ☞ docs you can group several methods at one priority. Here is a snippet to illustrate a generator with prompts split into two groups HTML and CSS:
'use strict';
var generators = require('yeoman-generator');
module.exports = generators.Base.extend({
constructor: function () {
generators.Base.apply(this, arguments);
},
prompting: {
prompt1: function() {
this.log("HTML")
var done = this.async();
this.prompt([{
type : 'input',
name : 'foo',
message : 'Foo',
}, {
type : 'input',
name : 'bar',
message : 'Bar'
}], function (answers) {
this.foo = answers.foo;
this.bar = answers.bar;
done();
}.bind(this));
},
prompt2: function() {
this.log("CSS")
var done = this.async();
this.prompt([{
type : 'input',
name : 'bam',
message : 'Bam',
}], function (answers) {
this.bam = answers.bam;
done();
}.bind(this));
}
},
configuring: function () {
console.log(this.foo, this.bar, this.bam);
}
});
Using this feature of Yeoman you could modularize your code even further, e.g. by putting your different prompts in separate code files and require / import them into your generator file. But basically the above snippet should do the trick.
Let me know if that helps.
The previous answer wasn't working for me until I made several modifications to the example code.
I can't be 100% certain, but I believe that the difference might be due to differing versions of the yeoman-generator module. So, I'm recording this here in case anyone else runs into the same issue.
For reference, I'm using yeoman-generator v0.23.4, yo v1.8.4, node v6.2.2, & npm v3.9.5.
Modifications:
Remove all instances of var done = this.async(); and done().
The async() function was causing the generator to exit after prompt1, and never run prompt2 or the configuring function.
Add return before calling this.prompt();
Removing async() causes the generator to rush through the prompts without waiting for an answer. Adding return fixes this.
Replace the callback function inside this.prompt() with .then().
Before making this change, the generator would run through the prompts correctly, but would not save the answers, and configuring would simply log undefined undefined undefined.
Original: this.prompt(prompts, callback(answers).bind(this))
Revised: this.prompt(prompts).then(callback(answers).bind(this));
Full Example:
'use strict';
var generators = require('yeoman-generator');
module.exports = generators.Base.extend({
constructor: function () {
generators.Base.apply(this, arguments);
},
prompting: {
prompt1: function() {
this.log("HTML")
return this.prompt([{
type : 'input',
name : 'foo',
message : 'Foo',
}, {
type : 'input',
name : 'bar',
message : 'Bar'
}]).then(function (answers) {
this.foo = answers.foo;
this.bar = answers.bar;
}.bind(this));
},
prompt2: function() {
this.log("CSS")
return this.prompt([{
type : 'input',
name : 'bam',
message : 'Bam',
}])
.then(function(answers) {
this.bam = answers.bam;
}.bind(this));
}
},
configuring: function () {
console.log(this.foo, this.bar, this.bam);
console.log('Config: ', this.config);
},
});

Resources