I have been trying for a while to learn how to build mobile apps with Javascript, and honestly I have no idea how anyone is able to do anything. Everything is broken. Every tutorial I've tried has failed to work for some bizarre reason. I am at my wits end.
I've finally decided to try and be even simpler, and just do the most basic tutorial I can find. What could go wrong. Well, it only took 3 pages of almost no code to completely stop working. I've done this, and I cannot insert anything to my db. My app fetches no data. When trying to add a new task, it gets added then disappears almost immediately, with a message stating insert failed: Method '/tasks/insert' not found (not even an error with some traceback).
The code really couldn't be simpler:
// imports/api/tasks.js
import { Mongo } from 'meteor/mongo';
export const Tasks = new Mongo.Collection('tasks');
// imports/ui/App.js
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import { withTracker } from 'meteor/react-meteor-data'
import { Tasks } from '../api/tasks.js';
import Task from './Task.js';
// App component - represents the whole app
class App extends Component {
handleSubmit(event) {
event.preventDefault();
// find the text field via the react ref
const text = ReactDOM.findDOMNode(this.refs.textInput).value.trim();
Tasks.insert({ text, createdAt: new Date() });
// Clear form
ReactDOM.findDOMNode(this.refs.textInput).value = '';
}
renderTasks() {
return this.props.tasks.map((task) => (
<Task key={task._id} task={task} />
));
}
render() {
return (
<div className="container">
<header>
<h1>Todo List</h1>
<form className="new-task" onSubmit={this.handleSubmit.bind(this)} >
<input
type="text"
ref="textInput"
placeholder="Type to add new tasks"
/>
</form>
</header>
<ul>
{this.renderTasks()}
</ul>
</div>
);
}
};
export default withTracker(() => {
return {
tasks: Tasks.find({}).fetch(),
};
})(App);
What is wrong? What am I missing?
The tutorial is indeed out of date and should be updated.
Background
In June 2017 there was a big security issue with allow/deny identified and the feature has been blocked since then.
Meteor allowed you to define client collection, that automatically synced with the server when the methods insert, update, remove were called on the client.
In order to control the access permissions, the allow/deny feature was implemented.
Now without allow/deny you will get the insert failed: Method '/tasks/insert' not found when classing SomeCollectionOnClient.insert but since this feature is obsolete (you will even get a big warning when setting it up), you need to create a server side method and call it from the client in order resolve this issue:
On the server create this method and ensure it is in the import chain from server/main.js:
new ValidatedMethod({
name: 'tasks.insert',
validate(args) {
// better use simpl-schema here
if (!args.text || !args.createdAt) {
throw new Meteor.Error('incompleteArgs', 'args are incomplete')
}
},
run (args) {
// check user permissions...
return Tasks.insert({ text, createdAt })
}
})
In your client component you can then call it via:
// find the text field via the react ref
const text = ReactDOM.findDOMNode(this.refs.textInput).value.trim();
Meteor.call('tasks.insert', {text, createdAt: new Date()}, (err, res) => {
// do something on err / on res
})
Note that this couples your component to the server side method and you may rather try to implement some containers for your pages that handle all the connection / pub-sub / method calling activity wile your components solely render content.
More to read / used in this answer:
https://guide.meteor.com/react.html
https://guide.meteor.com/security.html
https://docs.meteor.com/api/methods.html#Meteor-call
https://guide.meteor.com/methods.html#validated-method
Related
As the title suggests, how do you create a password protected React website? Nothing fancy beyond that. Everyone would have access to the same password, no need to do anything super secure, just simply to access the content on the React app.
This is new to me, so I'm not sure the proper steps to take. This is just to protect the content in on the frontend, and it doesn't need to be super secure, mostly to make sure we weed out any truly unauthorized access while our event is going on.
You could add the password-checking logic to your login component. Here are some ideas
Opt 1: use a library, see react-app-protect
Note: this currently only works with React 17 or lower
Opt 2: using input + DOM element search
import React, { useState } from "react";
const Login = () => {
const [isVerified, setIsVerified] = useState(false);
const checkPw = () => {
// gets the current input value
const answer = document.getElementById("password").value;
if (answer === "yourSecretPassword") {
setIsVerified(true);
} else {
alert("Sorry, that's not it");
}
};
return (
<>
{isVerified ? <YourApp />
:
(
<form onSubmit={checkPw}>
<input id="password" name="password" />
<button>open sesame</button>
</form>
)
}
</>
;
^ This is pretty janky, but it sounds like you're not worried about best-practices.
import React, { Component } from 'react';
import tableau from 'tableau-api';
class App extends Component {
componentDidMount() {
this.initViz()
}
initViz() {
const vizUrl = 'http://public.tableau.com/views/RegionalSampleWorkbook/Storms';
const vizContainer = this.vizContainer;
let viz = new window.tableau.Viz(vizContainer, vizUrl)
}
render() {
return (
<div ref={(div) => { this.vizContainer = div }}>
</div>
)
}
}
export default App;
it works when i publish my workbook to public tableau with extract data source
but when i publish the same in tableau with live data source(sql),
I obtained a url,
https:///#/site/testsite/views/genderanalysis/Sheet2?:iid=1
and that when i used here not working
and from the doc, i found api with unique-token
https:// /trusted/%3CTRUSTED%20TICKET%20HERE%3E/t/testsite/views/genderanalysis/Sheet2?:embed=yes&:comments=no&:toolbar=yes&:refresh=yes&:embed=y&:showVizHome=n&:jsdebug=y&:bootstrapWhenNotified=y&:apiID=handler0
But i dont know how to generate unique-token
when i browse it on a website it shows token error
i used https:///trusted/ with username as param, but it always returns -1
im using trial version
Did this worked for anyone?
It looks like you are trying to use Trusted Authentication but haven't done the steps necessary to create and use tokens. First, you need to configure Tableau Server to accept and trust requests from the server you will be embedding the dashboards in. Once you've done that you will be able to make POST requests for tokens from your web server. That is the time you use the username and other parameters. You will then receive a token that you can use to construct the URL for the view. Hope this helps!
I am quite new and having some difficulties getting an output when running a GraphQL query on a shopify scriptTag.
My current code looks like:
const test4 = gql`
query {
scriptTags(first: 4) {
edges {
node {
id
src
}
}
}
}
`;
const GiveData = () => (
<Query query={test4}>
{({ loading, error, data }) => {
if (loading) return "Loading...";
if (error) return `Error! ${error.message}`;
return (
<div>
<p> hi1 </p>
{data.scriptTags.edges.map(({ node }) => (
<div key={node.src}>
<p>
hi2 {node.src}
</p>
</div>
))}
</div>
);
}}
</Query>
);
My page is rendering the "hi1" text paragraph, but the "hi2" and actual data never loads. My console is also not outputting any error.
The query code itself works perfectly if I run it through the Shopify GraphiQL App, so I assume it isn't that. I believe I am doing something wrong within the GiveData constant, but not sure what.
Thanks in advance for any help or hints.
More context:
I have a basic shopify app setup, using react + node.js setup (based on shopify's templates & tutorial).
My server.js file has the script tag scopes included:
...
createShopifyAuth({
apiKey: SHOPIFY_API_KEY,
secret: SHOPIFY_API_SECRET_KEY,
scopes: ['read_products', 'write_products', 'read_script_tags', 'write_script_tags'],
...
I have been able to write a script tag, as it shows up in the
Shopify GraphiQL App. Screenshot of output
.
I am also able to get an output from a different GraphQL query. For example this
const test3 = gql`
query {
shop {
id
}
}
`;
with the same basic GiveData constant above, will output a result if I have ...{data.shop.id}... in my return field.
I am primarily wanting to query the script tags I've been able to write myself (not anything outside my app).
It would help to know the context of your call. In Shopify GraphiQL, clearly you are authenticated, the end point is set, all is well. Move away from that and your responsibilities mount. You can query using a private App API password, or a regular App with an oAuth token that has scoped access to script tags. Which are you?
Without knowing more about what you are doing, it is hard to help you along. Also, the liklihood that Shopify will show you any script tags that do not belong to the API key that created them ie) yours, is minimal.
I am new to React and RN. I have looked into every single solution here but I did not find a solution for my case. I am trying to pull google calendar events from calendar v3 api. I have tried two ways, so far. I don't know which one is correct but I did not get a correct result for any of them. Firstly, I have tried to send a request to the https://www.googleapis.com/calendar/v3/calendars/${CALENDAR_ID}/events?key=${API_KEY}( I don't know if the key parameter is needed. I think we should delete key parameter in front of the api key.I did it like that because otherwise it was giving an error as global not found).
This is calendar.js
const CALENDAR_ID = 'public#qeqw'
const API_KEY = 'key'
let url = `https://www.googleapis.com/calendar/v3/calendars/${CALENDAR_ID}/events?key=${API_KEY}`
export function getEvents (callback) {
request
.get(url)
.end((err, resp) => {
if (!err) {
const events = []
JSON.parse(resp.text).items.map((event) => {
events.push({
start: event.start.date || event.start.dateTime,
end: event.end.date || event.end.dateTime,
title: event.summary,
})
})
callback(events)
}
})
}
This is app.js
import React from 'react'
import { render } from 'react-dom'
import { getEvents } from './gcal'
import { View, Text,
StatusBar,Image,AppRegistry,ScrollView,StyleSheet,Platform,FlatList} from
'react-native'
class App extends React.Component {
constructor () {
super()
this.state = {
events: []
}
}
componentDidMount () {
getEvents((events) => {
this.setState({events})
})
}
render () {
return (
// React Components in JSX look like HTML tags
<View>
<Text>{this.state.events}</Text>
</View>
)
}
}
However, I got an error in the below. I don't know what I am doing wrong but it should be possible to send a request like that. My only concern is that if I need to get token by giving my client information by using OAuth2 authentication. Do I need to sign up and and get token to reach the API? If I need to do it, I have implemented to do it in node js by reading the sample here.https://developers.google.com/calendar/quickstart/nodejs but there are some node modules which I cannot use them in my React native application like fs, googleAuth, readline etc... Some of them can be done by using nodeify but others throw an error. So, I don't know what to do from now on. If someone can guide me how I would use google calendar api in react, I'd be appreciated. Thanks to the everyone who contributes here.
{
"error": {
"errors": [
{
"domain": "usageLimits",
"reason": "dailyLimitExceededUnreg",
"message": "Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup.",
"extendedHelp": "https://code.google.com/apis/console"
}
],
"code": 403,
"message": "Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup."
}
}
As the error message indicates, you are beyond your usage for that API.
You need to sign up in order to continue to use the API.
Once you sign up, you can use a library like Request-Promise in order to make the API request.
OR
You can search npm for a react component that interfaces with the Google Calendar API, such as this one
The error is caused from an silly mistake. The key parameter in the url should not be in parenthesizes. The reason it did not work is that the parameter key which is in front of the api key is in parenthesize. If you delete it, it works like a charm.
I am trying to call REST endpoints on one application (spring-boot) from another (reactjs). The applications are running on the following hosts and ports.
REST application, using spring boot, http://localhost:8080
HTML application, using reactjs, http://localhost:9000
I am trying to send the login info from reactjs to spring-boot but without success.
Reactjs:
import React from 'react';
export default class Login extends React.Component {
constructor() {
super();
this.state = {
login:"",
password:""
};
this.handleChange = this.handleChange.bind(this);
}
handleChange() {
this.setState({login: this.state.login});
}
render() {
return (
<form role="form">
<div>
<input type="text" name="login" onChange={this.handleChange} />
<input type="password" name="password"/>
</div>
<button onClick={this.login.bind(this)}>Login</button>
</form>
);
}
login () {
var xmlhttp = new XMLHttpRequest(); // new HttpRequest instance
var url = "http://localhost:8080/test/login"
xmlhttp.open("POST", url );
xmlhttp.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
xmlhttp.send(JSON.stringify({login: this.state.login}));
}
}
and Spring-boot:
#CrossOrigin(origins = "http://localhost:9000")
#RequestMapping(value = "/test/login")
public Boolean testLogin(#RequestParam String login) {
if ( login.equals ("ajt"))
return true;
else {
return false;
}
}
I can see that the two apps are connecting for even though reactjs gives me error 400, when I submit, the console of the Spring-boot app tells me:
Resolved exception caused by Handler execution: org.springframework.web.bind.MissingServletRequestParameterException: Required String parameter 'login' is not present
I can only assume that from the Spring-boot side, it cannot translate what ever is sent via react.js.
ps: bear with me, I have been coding for about 6 months.
I knew this looked familiar. Sorry my last answer didn't fix all your issues.
Your current problem is here;
public Boolean testLogin(#RequestParam String login) {
Should be
public Boolean testLogin(#RequestBody String login) {
EDIT:: Second problem.
Your handleChange function isn't taking in any values! It should look more like this;
handleChange(value) {
this.setState({login: value});
}
When your input field calls this function, it needs to pass a value from the input into the state. Your current code is essentially the same as this;
this.state.login = this.state.login;
Which obviously isn't going to get you anywhere.
Try that change. If it still does not work, be sure you open your dev-tools in your browser and step through the code line by line to be sure it is executing and storing the values you want it to.