I am working on a front end of a project and I am stuck for a while.
I have created an api with django rest framework and I am trying to connect to a Nextjs front end. The data is to show on the front page that is why I call getInitialProps. Following is the code
import styles from '../styles/Home.module.css';
import axios from 'axios';
const Home = ({ listings, error }) => {
if (error) {
return <div>An error occured: {error.message}</div>;
}
return (
<ul>
{listings.map((listing) => (
<li key={listing.address}>{listing.title}</li>
))}
</ul>
);
};
Home.getInitialProps = async (ctx) => {
try {
const res = await axios.get('http://127.0.0.1:8000/api/listings/?page=4');
const rep = await res.data;
console.log(rep.results);
listings = rep.results;
return { listings };
} catch (error) {
return { error };
}
};
export default Home;
In the console log I get the data, which is in the bellow format:
[
{
index: 1734112,
user: 11233,
title: 'Classical style',
address: 'address 23, city , country',
bedrooms: '2',
bethrooms: '1',
price: '5803',
list_type: 'rent'
},
{
index: 1722303,
user: 32119,
title: 'Pangrati On the Lake',
address: 'address 28, city , country',
bedrooms: '1',
bethrooms: '1',
price: '4800',
list_type: 'rent'
}
]
But I get an error occured in the browser without specifying the error.
And in the console I get the bellow.
next-dev.js?3515:32 Warning: Did not expect server HTML to contain the text node "listings is not defined" in <div>.
at div
at Home (webpack-internal:///./pages/index.js:50:26)
at MyApp (webpack-internal:///./pages/_app.js:38:27)
at ErrorBoundary (webpack-internal:///./node_modules/next/dist/compiled/#next/react-dev-overlay/client.js:8:20584)
at ReactDevOverlay (webpack-internal:///./node_modules/next/dist/compiled/#next/react-dev-overlay/client.js:8:23125)
at Container (webpack-internal:///./node_modules/next/dist/client/index.js:359:9)
at AppContainer (webpack-internal:///./node_modules/next/dist/client/index.js:793:26)
at Root (webpack-internal:///./node_modules/next/dist/client/index.js:915:27)
I am not sure what the issue is so any help much appreciated. Thank you!
You are assigning value to some variable listings = rep.results;, but this variable was not declared, you can't do that in strict mode (which I believe is default in that case)
So just declare it as const and the error should go away:
const listings = rep.results
Related
When I submit card details from frontend it fails to successfully POST in Django Rest server.
I think the error with Django code. If you know how to configure strip with Django, please help
DJANGO VIEWS.PY
#csrf_exempt
def chargeview(request,*args,**kwargs): # new
if request.method == 'POST':
charge = stripe.Charge.create(
amount=500,
currency='usd',
description='A Django charge',
source=request.POST['token']
)
return render(request, 'payments/charge.html')
ERROR
raise MultiValueDictKeyError(key)
django.utils.datastructures.MultiValueDictKeyError: 'stripeToken'
REACT JS CODE
import React, { useState } from "react";
import StripeCheckout from "react-stripe-checkout";
import axios from 'axios';
const StripeBtn = () => {
const publishableKey = "pk_test_some key";
const price = 1000
const onToken = token => {
const body = {
amount: 1000,
token: token
};
console.log(body.token)
axios
.post("http://localhost:8000/payments/", {token:body.token})
.then(response => {
console.log(response);
})
.catch(error => {
console.log("Payment Error: ", error);
alert("Payment Error");
});
};
return (
<StripeCheckout
label="Go Premium" //Component button text
name="Business LLC" //Modal Header
description="Upgrade to a premium account today."
panelLabel="Go Premium" //Submit button in modal
amount={price} //Amount in cents $9.99
token={onToken}
stripeKey={publishableKey}
image="" //Pop-in header image
billingAddress={false}
/>
);
};
export default StripeBtn;
RESULTANT TOKEN FROM REACT FRONTEND THAT PASS TO DJANGO USING AXIOS
{id: "tok_1G***WLSNV4Son7o8TBJY", object: "token", card: {…}, client_ip: "***", created: ***, …}
card: {id: "card_1Gmn7*****oPKqrwrXa", object: "card", address_city: null, address_country: null, address_line1: null, …}
client_ip: "1***77"
created: 15***39325
email: "anoop***il.com"
id: "tok_1Gm***4Son7o8TBJY"
livemode: false
object: "token"
type: "card"
used: false
In my component template I have a v-alert vuetify sub-component
<v-alert dismissible #input="closeAlert()" #type="msgTypeContactForm" v-model="msgStatusContactForm">{{ msgValueContactForm }}</v-alert>
using the following data
data() {
return {
...
msgStatusContactForm: false,
msgTypeContactForm: "",
msgValueContactForm: ""
};
},
on submitting the form, when an error is raised , I set these data
catch (err) {
this.msgTypeContactForm = "error";
this.msgValueContactForm = this.$i18n.t("lang.views.home.contactForm.post_error");
this.msgStatusContactForm = true;
This is running fine, the alert is correctly displayed with the correct type and value ..
However in the component unit test , the alert properties and value are not updated in the template
it("should not sendMessage - invalid form", async () => {
...
wrapper = mount(ContactForm, options);
const contactForm = wrapper.find("form");
...
const btnSubmit = wrapper.find("#btnSubmit");
btnSubmit.trigger("click");
await wrapper.vm.$nextTick();
// then
setTimeout(() => {
expect(wrapper.vm.validForm).toEqual(false);
expect(wrapper.vm.msgStatusContactForm).toEqual(true);
expect(wrapper.vm.msgTypeContactForm).toEqual("error");
}, 2000);
await wrapper.vm.$nextTick();
const alert = wrapper.find(".v-alert");
console.log("INVALID FORM ALERT: ", alert.html());
})
console.log tests/unit/ContactForm.spec.js:383
INVALID FORM ALERT: cancel
the alert should be displayed and the type set and message value present in the html output ....
I don't know where I am wrong in my test ? any help appreciated
SOLVED..
It's a matter of handling async/await function... in my component
submitForm: async function() {
....
So I use flush-promises in my test
yarn add -D flush-promises
then
import flushPromises from "flush-promises";
...
it("should not sendMessage - invalid form", async () => {
...
wrapper = mount(ContactForm, options);
...
// then
const btnSubmit = wrapper.find("#btnSubmit");
btnSubmit.trigger("click");
await flushPromises();
...
const alert = wrapper.find(".v-alert");
console.log("INVALID FORM ALERT: ", alert.html());
Then I can see the DOM updated
<div class="v-alert error" style=""><div>One or more fields are invalid. Please, review your input and submit</div><a class="v-alert__dismissible"><i aria-hidden="true" class="v-icon v-icon--right material-icons theme--light">cancel</i></a></div>
I'm totally new to both Apollo and GraphQL. I'm following along with this apollo-link-state-tutorial, and am hitting a stumbling block.
I have set up my link with a currentGame property default.
const stateLink = withClientState({
cache: stateCache,
defaults: {
currentGame: {
__typename: 'currentGame',
teamAScore: 0
}
}
})
I'm using it in my client.
const client = new ApolloClient({
stateCache,
link: stateLink,
...
})
I'm defining a GraphQL query like this:
const getCurrentGame = gql`
query {
currentGame #client {
teamAScore
}
}
`
I am connecting it to my component's props.
export default compose(
graphql(getCurrentGame, {
props: ({ data: { currentGame }}) => ({
currentGame
})
})
)
This generates an error in the console.
[GraphQL error]: Message: Field 'currentGame' doesn't exist on type 'Query', Location: [object Object], Path: undefined
I've gone over my code and haven't been able to spot what is surely a typo or simple mistake. How can I debug this error message, or what does it suggest the problem is?
Update: I have tried adding a resolver as suggested by Tal Z, but am still receiving the same error message.
const stateCache = new InMemoryCache()
const stateLink = withClientState({
cache: stateCache,
resolvers: {
Query: {
currentGame: () => {
return {}
}
}
},
defaults: defaultState
})
For what it's worth, most of the few example repositories I've found have queries for fields that do not have resolvers defined. For example, this queries for todo list items, but the only resolver defined is for a mutation.
Well, I figured it out... this breaks:
import ApolloClient from 'apollo-boost'
This works:
import ApolloClient from 'apollo-client'
I have no idea what the difference is.
I am trying to fill a Text Input and verify that the text is filled correctly, accessing the component and getting its value.
I have succeeded in doing so, but without using redux, ie using the native states of react-native. this.state.
Component Code:
//inside constructor
this.state = {
email: ''
}
<TextInput value={this.state.email} onChangeText={(text) => {
console.log('Here change email text!!! ==> ', text);
this.setState({
email: text
})
}} />
Test File Code:
import LoginScreen from '../../App/Containers/LoginScreen' // => connected component.. exported with `export default connect(mapStateToProps, mapDispatchToProps)(LoginScreen)`
import configureStore from 'redux-mock-store'
import { shallow } from 'enzyme'
import Actions, { reducer, INITIAL_STATE } from '../../App/Redux/Reducers/UserReducer'
const initialState = {
user: {
email: 'mockState email',
password: '',
requesting: 0,
userData: null,
loginFinish: false,
errorMessage: null
}
}
const mockStore = configureStore([]);
let store = mockStore(initialState);
const wrapper = shallow(
<LoginScreen/>,
{ context: { store: store } },
);
test('>>>>> LoginScreen component renders correctly', () => {
expect(wrapper.dive()).toMatchSnapshot();
});
test('>>>>> Login button Press', () => {
let render = wrapper.dive();
const textInputProps = render.find('TextInput'); //getting text input from render
console.log(`textInputProps.getNode(1).props.value BEFORE ====>`, textInputProps.getNodes()[0].props.value);
textInputProps.first().simulate('changeText', 'My new value'); // executing onChangeText inside render of component
const textInputProps2 = render.find('TextInput'); //getting text input again for check changes
console.log(`textInputProps2.getNode(1).props.value====>`, textInputProps2.getNodes()[0].props.value);
const state = store.getState(); //verifying internal `initialState`.. NOT CHANGES
console.log('state ===> ', state);
});
I have relied on this link
Running test logs
yarn test v0.24.6
$ jest
PASS Tests/Containers/loginScreenTest.js
✓ >>>>> LoginScreen component renders correctly (282ms)
✓ >>>>> Login button Press (33ms)
console.log Tests/Containers/loginScreenTest.js:60
textInputProps.getNode(1).props.value BEFORE ====>
console.log App/Containers/LoginScreen.js:124
Here change email text!!! ==> My new value
console.log Tests/Containers/loginScreenTest.js:67
textInputProps2.getNode(1).props.value====> My new value => (!!!WORKS!!!)
console.log Tests/Containers/loginScreenTest.js:86
state ===> { user:
{ email: 'mockState email',
password: '',
requesting: 0,
userData: null,
loginFinish: false,
errorMessage: null } }
Test Suites: 1 passed, 1 total
Tests: 2 passed, 2 total
Snapshots: 1 passed, 1 total
Time: 2.337s, estimated 3s
Ran all test suites.
✨ Done in 3.10s.
as you can see in the logs textInputProps2.getNode(1).props.value ====> show me the value as expected.
So far so good
Now passing everything to a reducer, with the redux structure, we will see the text input as follows
<TextInput value={this.props.user.email} style={styles.textInputs} placeholder={'Email'} autoCapitalize={'none'} onChangeText={(text) => {
console.log('Here change email text!!! ==> ', text);
this.props.email_typing(text);
}} />
Connected logic
const mapStateToProps = (state) => {
return {
user: state.user
}
}
const mapDispatchToProps = (dispatch) => {
return {
email_typing: (text) => dispatch(UserReducer.email_typing(text)),
}
}
export default connect(mapStateToProps, mapDispatchToProps)(LoginScreen)
My UserReducer File
import { createReducer, createActions } from 'reduxsauce'
import Immutable from 'seamless-immutable'
/* ------------- Types and Action Creators ------------- */
const { Types, Creators } = createActions({
email_typing: ['email'],
})
export const LoginTypes = Types
export default Creators
/* ------------- Initial State ------------- */
export const INITIAL_STATE = Immutable({
email: ''
})
/* ------------- Reducers ------------- */
// state.merge undefined error: https://github.com/infinitered/ignite/pull/20#issuecomment-202550408. Fixed including in Inmutable
export const emailTyping = (state, { email }) => {
console.log('Email Typing changes !!! in original reducer')
return Immutable(state).merge({ email })
}
/* ------------- Hookup Reducers To Types ------------- */
export const reducer = createReducer(INITIAL_STATE, {
[Types.EMAIL_TYPING]: emailTyping,
})
Given this change, the idea is that the initialState within the Test File changes to INITIAL_STATE imported value.
Something like:
const mockStore = configureStore([]);
let store = mockStore(INITIAL_STATE);
but, when i run the test again. Show me the next error:
● >>>>> LoginScreen component renders correctly
TypeError: Cannot read property 'email' of undefined
even if I keep the initialState instead of the INITIAL_STATE, I do not get the above error, but I can not get the text input to take the change.
Running Test Logs
yarn test v0.24.6
$ jest
PASS Tests/Containers/loginScreenTest.js
✓ >>>>> LoginScreen component renders correctly (345ms)
✓ >>>>> Login button Press (24ms)
console.log Tests/Containers/loginScreenTest.js:58
textInputProps.getNode(1).props.value BEFORE ====> mockState email
console.log App/Containers/LoginScreen.js:120
Here change email text!!! ==> My new value
console.log Tests/Containers/loginScreenTest.js:61
textInputProps2.getNode(1).props.value====> mockState email => **(!! HERE !!!, THE VALUE IS BEING THE PREVIOUS ONE AND IGNOR THE CHANGE)**
console.log Tests/Containers/loginScreenTest.js:79
state ===> { user:
{ email: 'mockState email',
password: '',
requesting: 0,
userData: null,
loginFinish: false,
errorMessage: null } }
Test Suites: 1 passed, 1 total
Tests: 2 passed, 2 total
Snapshots: 1 passed, 1 total
Time: 2.904s
Ran all test suites.
✨ Done in 3.68s.
Check textInputProps2.getNode(1).props.value====> log to check that this is not useful.
I think that the const initialState declared inside test file It is not being affected by the changes made in the actual reducer when this.props.email_typing(text) action is called;
I have not found the way to connect the actions with the states in the reducer and to be able to load them inside JEST.
I know it's a bit long and I appreciate your time reading it.
I tried to leave it the best explained and as much information as possible.
Thank you very much and I look forward to any response.
I guess you want to do some integration test here. It is possible to achieve what you are trying like that :
import { createStore, combineReducers } from 'redux';
import { reducer } from '.../UserReducer';
// create a real store with the needed reducer(s)
const store = createStore(combineReducers({ user: reducer }));
const wrapper = shallow(
<LoginScreen/>,
{ context: { store } },
);
// ...
test('>>>>> Login button Press', () => {
let render = wrapper.dive();
const textInputProps = render.find('TextInput');
console.log(`value BEFORE ====>`, textInputProps.getNodes()[0].props.value);
textInputProps.first().simulate('changeText', 'My new value');
// Force the component to update after changing state
render = wrapper.update().dive();
const textInputProps2 = render.find('TextInput');
console.log(`value AFTER ====>`, textInputProps2.getNodes()[0].props.value);
const state = store.getState();
console.log('state ===> ', state);
});
I tried with a minimal implementation, here is the console result:
console.log src/Test.test.js:27
value BEFORE ====>
console.log src/Test.test.js:35
value AFTER ====> My new value
console.log src/Test.test.js:38
state ===> { user: { email: 'My new value' } }
I am trying out Urban Airship with Appcelerator but I am having problems with using it.
This is my code in App.js:
Will it be "activated" when the user opens the app and then register automatically with Urban Airship?
UrbanAirship = require('ti.urbanAirship');
Ti.API.info("module is => "+UrbanAirship);
Ti.include('common/urbanairship.js');
UrbanAirship.key='XXX';
UrbanAirship.secret ='XXX';
UrbanAirship.master_secret='XXX';
UrbanAirship.baseurl = 'https://go.urbanairship.com';
Ti.Network.registerForPushNotifications({
types: [
Ti.Network.NOTIFICATION_TYPE_BADGE,
Ti.Network.NOTIFICATION_TYPE_ALERT,
Ti.Network.NOTIFICATION_TYPE_SOUND
],
success:function(e){
var deviceToken = e.deviceToken;
Ti.API.info('successfully registered for apple device token with '+e.deviceToken);
var params = {
tags: ['version'+Ti.App.getVersion()],
alias: 'testing'
};
UrbanAirship.register(params, function(data) {
Ti.API.debug("registerUrban success: " + JSON.stringify(data));
}, function(errorregistration) {
Ti.API.warn("Couldn't register for Urban Airship");
});
},
error:function(e) {
Ti.API.warn("push notifications disabled: "+e);
},
callback:function(e) {
var a = Ti.UI.createAlertDialog({
title:'New Message',
message:e.data.alert
});
a.show();
}
});
The modules are always hit or miss for me.
Very rarely have they worked without a lot of troubleshooting.
I've gone the old-school route and it has worked fine for me - although I did change urbanairship.js to add eventlisteners on windowfocus to the register/alias fields in the final app.
But for testing just leave as is. Hope this helps - http://wiki.appcelerator.org/display/guides/Push+Notifications