How to pass cardElement to createPaymentMethod(cardElement, customerId, priceId) React+Stripe? - html

I have their <CardSection /> element in a SignUp form component, on submit I authenticate the user, create the customer, but can't figure out how to pass the <CardSection /> to the createPaymentMethod function.
Some of what I have:
SignUp form:
handleSignUp = (event) => {
event.preventDefault();
let cardElement = document.getElementById('#cardElement');
signUp(this.state.email, this.state.password, cardElement);
}
Where signUp() looks like:
import firebase from './firebase.js';
import { createCustomer } from './createCustomer.js';
import { createPaymentMethod } from './createPaymentMethod.js';
export function signUp(email, password) {
firebase.auth().createUserWithEmailAndPassword(email, password).catch(function(error) {
// Handle Errors here.
console.log(`Error in signUp ${error.code}: ${error.message}`);
});
createCustomer().then((customer) => {
let customerId = customer.customer.id;
let priceId = "price_HIsuBNTXc2NQ7L";
createPaymentMethod(cardElement, customerId, priceId);
});
}
This doesn't work (I get TypeError: JSON.stringify cannot serialize cyclic structures.), and I think I'm doing this plain incorrectly. What's the right way to do this part?
The documentation (https://stripe.com/docs/billing/subscriptions/fixed-price) seems to skip this step going from step 4 to 5. I'm pretty green with Stripe and React so take it easy on me. What am I missing here?

I believe Erwan Daniel's comment is correct and your signUp function is missing an argument. Its signature should probably be:
export function signUp(email, password, cardElement)

Related

Get json data in VueJS

onMounted(() => {
productService.value
.getProducts()
.then((data) => (products.value = data));
console.log((products))
});
When I print products with console.log, here what I have.
capture of the console
I see that the data I want are in RawValue but I don't know how to access them.
I tried Object.values(products) or just console.log(products._rawValue) or console.log(products.rawValue) it print undefined.
Do you know what function call ?
Thanks
There are 2 issues
#1 - you're using console.log(products) which shows you the reactive object, what you need instead is console.log(products.value) which will only show the value, which should match the content of data.produtcs
#2 - you might find that 👆 now shows an empty result. The reason that's happening is that you're calling the console log after the async function, but before it finishes, so you're calling it before it has a chance to update. To fix that, you can log as part of the async function
onMounted(() => {
productService.value
.getProducts()
.then((data) => {
products.value = data;
console.log(products.value);
})
});
If you're using the products inside a template, you don't need to worry about what's before or after the async function since it will re-render the component on change.
Also, you probably don't need to define productService as a ref, the class is likely not something that needs to be reactive, so you can just do simple assignment and then skip the .value to call getProducts
with axios what I do is take out the data with response.data you could try
onMounted(() => {
productService.value.getProducts().then((response) => (
products = response.data
));
console.log(products.length);
});

Add information to List in Angular

I'm learning Angular 6 and I have a List shown on my site. Now, i need to give Users of my site the possibility to add entries to that list. There's a form with 4 fields and a submit button, when Submit is clicked, the values should be stored anywhere and all the entries should be shown on the site, permanently, not just in the active session.
How can i achieve this? Do i need to include some sort of database? Or is it possible to append the new dataset to a JSON file?
Thank you in advance
EDIT: This is a training project and will only be available through the Intranet of the Company i work at, so security concerns about missing Captchas or similar things are not a factor
If you are going to use this project for long time and if number of entries is higher and you have alot of users, then you should use some data base. And if there is limited number of users and you need this app temporary then using json file is also good. Using json file will save you from database logics etc if you are not familiar with them
To SAVE some data anywhere you HAVE TO use some kind of database.
Angular is JavaScript framework. It helps to write applications. But it does nothing with server side (except, of course, CLI and other stuff which NodeJS people likes to do).
JSON is not the only way to communicate between browser and the server. But in Angular it's easiest way.
You'll need something on the server (I suppose PHP script) which will receives data from your Angular app and will send back some feedback. In the case with PHP you'd learn how to receive JSON POST ($_POST and $_REQUEST will not work)
What I advise you in terms "how to learn Angular" is go to this step-by-step tutorial https://angular.io/tutorial
Run it twice or three times and you'll understand how works Promises, Observables, communications, templates, services and all other stuff.
It is possible to append the data to the new dataset to the JSON file create a service to read that JSON file using that service so to give you the basics of reading that JSON file
Config.service.ts
#Injectable()
export class ConfigService {
private static _config: any = {}
constructor(private _http: Http) { }
load() {
return new Promise((resolve, reject) => {
this._http.get('../assets/' + 'data.json')
.map(res => res.json())
.subscribe((data) => {
console.log("inside http get of the new service");
console.log(data);
ConfigService._config = data;
resolve(true);
},
(error: any) => {
console.error(error);
return Observable.throw(error.json().error || 'Server error');
});
});
}
// Gets a value of specified property in the configuration file
get(key: any) {
console.log("tell me the base :" + ConfigService._config['BASE_URL']);
return ConfigService._config[key];
}
}
export function ConfigFactory(config: ConfigService) {
return () => config.load();
}
export function init() {
return {
provide: APP_INITIALIZER,
useFactory: ConfigFactory,
deps: [ConfigService],
multi: true
}
}
const ConfigModule = {
init: init
}
export { ConfigModule };
add these lines in your main module
app.module.ts
import { CommonModule } from '#angular/common';
import { ConfigModule, ConfigService } from './config-service';
providers:[
ConfigService,
ConfigModule.init(),
]
Then, you can inject this service on any component or service that wants the data
Also, you have to add an assets folder under your app folder and place the data.json there.

React Unable to Access Json Resposne from API

In my website on login,i get a confirmation and a token which i need to store and pass as a property throughout all the pages.I am able to receive the token,but i am unable to store the value for the token and store it as a state value.
Here is the code i have tried so far.
import React from 'react'
import ReactDOM from 'react-dom'
import {Login_Submit_style,Login_button_style,Login_text_field_style,
password_style,para_login_style} from './style'
import Supers from 'superagent'
class Login extends React.Component
{
constructor(props)
{
super(props);
this.state={username:'',password:''}
this.Login_data_password=this.Login_data_password.bind(this)
this.Login_data_username=this.Login_data_username.bind(this)
this.MainRedirect=this.MainRedirect.bind(this)
this.api_call_login=this.api_call_login.bind(this)
}
Login_data_username(e)
{
this.setState({username:e.target.value})
}
Login_data_password(password)
{
this.setState({password:password.target.value})
}
MainRedirect()
{
window.location = '/main';
}
api_call_login()
{
Supers.post('http://127.0.0.1:8000/user_ops/user_login/')
.send({'username':this.state.username,'password':this.state.password})
.then(response => response.json())
.then(responseData=>{
console.log(responseData);
})
}
render()
{
return(
<div style={{background:'yellow'}}>
<div>
<h1 style={{marginLeft:550}}>Login Page</h1>
<div>
<p style={para_login_style}><b>Username</b></p>
<input type="text" style={Login_text_field_style} onChange={this.Login_data_username}/>
<h2>{this.state.username}</h2>
</div>
<div>
<p style={para_login_style} ><b>Password</b></p>
<input type="password" style={password_style} onChange={this.Login_data_password}/>
</div>
<div>
<button style = {Login_Submit_style} onClick={this.api_call_login}> Log in </button>
</div>
</div>
</div>
)
}
}
This is the Format in which i get the response:
{"Successful_Login": "True", "token": "d278f30445aa0c37f274389551b4faafee50c1f2"}
So ideally i would like to store the values for both the keys returned from the json output.Adn when i use response.body,i am able to get the data in the above format.
I don't know if this will be helpful to you, but I'll try.
Things like XHR calls from a browser to an API are done asynchronously. What you get back is a promise that will execute a function you give it when the call to the API is completed. Your code rightly has a callback function.
However, I don't think that callback function can call setState, because I think (I might be wrong) React wouldn't like it.
I use Redux for React as a way of storing stuff that the rest of the app can just grab when it needs it. Better still, Redux is integrated into React in such a way that whenever this central database is updated, any component that pulls in a piece of data from it (via props) gets updated (re-rendered) automatically.
I think I should point you to the documentation for Redux for more information. There are alternatives to Redux, too.
Good luck, and ask more questions if you get stuck.
In order to set a new state with the values from a json response, I ideally call this.setState right in your promise response.
api_call_login()
{
Supers.post('http://127.0.0.1:8000/user_ops/user_login/')
.send({'username':this.state.username,'password':this.state.password})
.then(response => response.json())
.then(responseData=>{
this.setState({
Successful_Login: responseData.Successful_Login,
token: responseData.token
})
}
state will be updated when response arrives.
If possible try to use lowercase or camelCase to your keys.
It would be great if you could post link where we can see what exactly is going on, but the way I understand this you would have to add .set('Accept', 'application/json') in your request to get correct json. So, your code should be like:
Supers.post('http://127.0.0.1:8000/user_ops/user_login/')
.send({'username':this.state.username,'password':this.state.password})
.set('Accept', 'application/json')
.then(response => response.json())
.then(responseData=>{
console.log(responseData);
})
Since I cannot test, you would have to look if it works. Alternatively, I would suggest you to try using superagent
Let me know if it helps!

Accessing state in React render method after API request

I'm working on my first complicated React app and I am making a request to a movie API. My site allows the user to do a search in a searchbar for whatever movie, show, actor, etc... that they are searching for. I'm pulling the user's search query and inserting it into an api request like this:
export const getDetails = (id) => {
return new Promise(function(resolve, reject) {
axios.get(`https://api.themoviedb.org/3/movie/` + id +`?api_key=&language=en-US`)
.then(function(response) {
resolve(response)
})
.catch(function(error) {
reject(error)
})
})
}
I'm able to get the data like this and console.log it:
import React, { Component } from 'react';
import Header from '../header';
import {Link} from 'react-router-dom';
import axios from 'axios';
import Footer from '../Footer.js';
import Searchbar from '../header/searchbar.js';
import List from '../results/list';
import {getDetails} from '../api/getDetails';
class Detail extends Component {
constructor(props) {
super(props);
this.state = {
id: this.props.match.params.id,
result: null,
error: false,
}
}
componentWillMount() {
getDetails(this.state.id).then(function(response){
this.setState({result: response});
console.log(response.data.original_title);
console.log(response.data.homepage);
console.log(response.data.popularity);
console.log(response.data.release_data);
console.log(response.data.overview);
}.bind(this)).catch(function(err) {
this.setState({
result:"There was a problem loading the results. Please try again.",
error: true
})
}.bind(this))
}
render() {
return(
<div>
<Header/>
<div className="details-container">
<h2>Details: </h2>
</div>
</div>
)
}
}
export default Detail
Console.logging it in the componentWillMount function successfully logs the data but I am not able to access the data in the render function via something like {response.data.orginal_title). How would I render the data being logged in componentWillMount?
TLDR; You can access your state variables from within your render function via this.state. Something like: console.log(this.state.result.data.origin_title) outside of the jsx and {this.state.response.data.orginal_title} inside the jsx.
P.S. You are using the correct this.
The following are picky recommendations and explanations, feel free to disregard.
It's recommended to make requests for data in componentDidMount. That can be read here in the docs for componentDidMount.
You're using arrow functions already in your get details function, if you convert the rest of your functions to arrow functions you no longer have to explicitly bind this to each one; it's automatically set be the this of it's parent. See the "No Separate This" section in the MDN docs
If you don't need any of the header information I would save response.data into your state so you don't have to type as much when you want to access the data. this.state.result.original_title vs this.state.result.data.original_title. That's just me and I'm lazy.
axios does return a promise like Eric said so you don't actually need to wrap it in the extra promise. You can just straight up return it and since arrow functions automatically return one line expressions you can spiff that up into a one liner:
export const getDetails = id => axios.get(`https://api.themoviedb.org/3/movie/${id}?api_key=&language=en-US`)
Finally you should be able to access the data you've stored in your state from your render function as mentioned in #3 above. Outside of the JSX you can console.log it like normal console.log(this.state.result), inside your JSX, however, you will need to make sure you escape with {} like: <div>{this.result.original_title}</div>
Small working example here: https://codesandbox.io/s/zqz6vpmrw3
You can simply use
{this.state.result}
inside the render.

Unable to retrieve field value for async validation in a redux form

It is how I set up my redux form
import React, { PropTypes } from 'react';
import { reduxForm, Field } from 'redux-form/immutable';
...
const asyncValidate = ( values, dispatch, props ) => {
// print out the value for inspection
console.log(`>>>> ${values.coupon}`);
}
...
const CheckoutForm = reduxForm({
form: 'Checkout',
asyncValidate,
})(cardDetailsForCheckoutForm);
The field I want to validate is called coupon. I need to validate it in an async manner because it requires a check on the server side. Somehow I cannot get the coupon value as values.coupon. It just returns as undefined
But according to the example (http://redux-form.com/6.0.0-rc.1/examples/asyncValidation/), I should be able to retrieve the value. Why it fails?
I find that after I restart the browser, the code works as expected.