React/Meteor Component not passing Props properly - mongodb

new to Meteor and running into this issue. I am using Meteor 1.3.3
When I try to pass props from my parent Container to my React Component it keeps throwing an error I will post below.
Here is my React component Prospect.jsx:
import React from 'react'
import { createContainer } from 'meteor/react-meteor-data'
import { Residents } from '/collections/residents.jsx'
import ReactDOM from 'react-dom';
import RaisedButton from 'material-ui/RaisedButton';
// import '/collections/residents.jsx'
class Prospect extends React.Component {
render() {
return(
<div>
<h1>Prospect Resident - {this.props.prospect.name.first} </h1>
<RaisedButton label="Default" />
</div>
)
}
}
Prospect.propTypes = {
// prospect: React.PropTypes.object
}
export default createContainer((params) => {
const paramsId = params.params.prospectId
Meteor.subscribe('residents');
// Meteor.subscribe('resident');
prospect = Residents.find({_id: paramsId}).fetch()
console.log(prospect[0])
return {
prospect: prospect
}
}, Prospect)
and here is my Mongo collection
residents.jsx
import { Mongo } from 'meteor/mongo'
export const Residents = new Mongo.Collection('residents')
const nameSchema = new SimpleSchema({
first: {type: String},
last: {type: String}
})
const residentSchema = new SimpleSchema({
cId: { type: String },
name: { type: nameSchema },
status: { type: String },
})
Residents.attachSchema(residentSchema)
// METHODS
Meteor.methods({
'residents.insert'(resident) {
Residents.insert(resident)
}
})
// PUBLICATIONS
if(Meteor.isServer) {
Meteor.publish('residents', function() {
return Residents.find()
})
Meteor.publish('resident', function(id) {
return Residents.find({_id: id})
})
}
and here is my Route
FlowRouter.route('/prospects/:prospectId}', {
name: 'prospectShow',
action(params) {
mount(LoggedIn, { content:
<MuiThemeProvider muiTheme={getMuiTheme()}>
<Prospect params={{prospectId: params.prospectId}} />
</MuiThemeProvider>
})
}
So when I go to localhost:3000 route I get the error
Prospect.jsx:14Uncaught TypeError: Cannot read property 'name' of undefined
Exception from Tracker recompute function:
debug.js:41 TypeError: Cannot read property '_currentElement' of null
at ReactCompositeComponentWrapper._updateRenderedComponent (ReactCompositeComponent.js:772)
at ReactCompositeComponentWrapper._performComponentUpdate (ReactCompositeComponent.js:753)
at ReactCompositeComponentWrapper.updateComponent (ReactCompositeComponent.js:672)
at ReactCompositeComponentWrapper.receiveComponent (ReactCompositeComponent.js:571)
at Object.receiveComponent (ReactReconciler.js:127)
at ReactCompositeComponentWrapper._updateRenderedComponent (ReactCompositeComponent.js:775)
at ReactCompositeComponentWrapper._performComponentUpdate (ReactCompositeComponent.js:753)
at ReactCompositeComponentWrapper.updateComponent (ReactCompositeComponent.js:672)
at ReactCompositeComponentWrapper.performUpdateIfNecessary (ReactCompositeComponent.js:585)
at Object.performUpdateIfNecessary (ReactReconciler.js:160)
My console.log(prospect[0]) in the container returns the object just fine, and it also works if I pass it in like this
return {
prospect: {name: {first: 'Joe', last: 'Smith'}}
}
So it's something about the returned object I think. Any help would be greatly appreciated, thanks

I ended up going with a solution like this. If anyone wants to answer and explain why this is needed (I thought in meteor 1.3 this wasn't needed anymore) I will accept your answer.
import React from 'react'
import { createContainer } from 'meteor/react-meteor-data'
import { Residents } from '/collections/residents.jsx'
class Prospect extends React.Component {
render() {
if(!this.props.ready){return <span>Loading...</span>}
const { prospect } = this.props
return(
<div>
<h1>{prospect.name.first} {prospect.name.last}</h1>
<div>Company: <b>{prospect.cId}</b></div>
</div>
)
}
}
Prospect.propTypes = {
ready: React.PropTypes.bool.isRequired,
prospect: React.PropTypes.object.isRequired
}
export default createContainer((params) => {
return {
ready: Meteor.subscribe('resident', params.id).ready(),
prospect: Residents.findOne(params.id)
}
}, Prospect)

Related

ConnectorError Prisma with MongoDB

I am developing an API with Nestjs and MongoDB. Well sometimes I have this problem. It doesn't always happen and that's what I have to solve because this error rarely happens.
This is the error:
{
"status": "error",
"message": "\nInvalid this.prisma.people.findMany() invocation in\nC:\ima\empresas\datec\api-official\src\modules\Events\services\utils.service.ts:57: 28\n\n 54 }),\n 55 \n 56 // Get attendees by id\n→ 57 this.prisma.people.findMany(\nError in batch request 3: Error occurred during query execution:\nConnectorError(ConnectorError { user_facing_error: None, kind: RawDatabaseError { code: "unknown", message: "An existing connection was forced to be terminated by the remote host. (os error 10054)" } })"
}
I really can't find much information to solve this error. I have followed the steps in the documentation on Nestjs when using prisma with nestjs. I need help to solve this error, since it is essential to find a solution as soon as possible. Thanks so much for read this question
UPDATE
The Prisma service
// Librarys
import { Injectable } from '#nestjs/common'
import { PrismaClient } from '#prisma/client'
// Interfaces
import { INestApplication, OnModuleInit, OnModuleDestroy } from '#nestjs/common'
#Injectable()
export class PrismaService
extends PrismaClient
implements OnModuleInit, OnModuleDestroy
{
async onModuleInit() {
await this.$connect()
}
async onModuleDestroy() {
await this.$disconnect()
}
async enableShutdownHooks(app: INestApplication) {
this.$on('beforeExit', async () => {
await app.close()
})
}
}
File that starts the application
//Libraries
import { NestFactory } from '#nestjs/core'
import { ValidationPipe } from '#nestjs/common'
import { SwaggerModule, DocumentBuilder } from '#nestjs/swagger'
import { useContainer } from 'class-validator'
// Modules
import { MainModule } from './main.module'
// config
import pk from '#root/package.json'
import { corstOptions } from '#config/cors'
import { PORT, APP_NAME, PUBLIC_URL } from '#config/env'
// Exceptions
import { HttpExceptionFilter } from '#utils/HttpExceptionFilter'
import { PrismaService } from '#root/src/services/prisma'
async function bootstrap() {
// Create application
const app = await NestFactory.create(MainModule)
// Enable cors
app.enableCors(corstOptions)
// Use global 'api' prefix, all calls will come after '/api/*'
app.setGlobalPrefix('api')
// Globally define custom response
app.useGlobalFilters(new HttpExceptionFilter())
// Enable prism on custom validations
useContainer(app.select(MainModule), { fallbackOnErrors: true })
// Get service from primsa and enable 'shutdowns'
const prismaService = app.get(PrismaService)
await prismaService.enableShutdownHooks(app)
// Use 'pipe' validation to validate the 'body' structure
app.useGlobalPipes(
newValidationPipe({
whitelist: true,
transform: true,
forbidUnknownValues: true,
forbidNonWhitelisted: true,
transformOptions: { enableImplicitConversion: true }
})
)
// Create API documentation
const config = new DocumentBuilder()
.addBearerAuth()
.setTitle(`API | ${APP_NAME}`)
.setContact(pk.author.name, pk.author.url, pk.author.email)
.setDescription(pk.description)
.setVersion(pk.version)
.build()
const document = SwaggerModule.createDocument(app, config)
SwaggerModule.setup('/', app, document)
// Listen to the application on the PORT defined in the environment variables
await app.listen(PORT || 0, () => {
// eslint-disable-next-line no-console
console.log(
'\x1b[33m%s\x1b[0m',
`[INFO] The server has been started at '${PUBLIC_URL}'`
)
})
}
bootstrap() // Run application
utils.service of Event module
// Librarys
import { Prisma } from '#prisma/client'
import { Inject, Injectable } from '#nestjs/common'
// Services
import { PrismaService } from '#services/prisma'
// DTO
import { EventBodyDTO } from '#modules/Events/events.dto'
// Arguments
import { EventsArgs } from '#modules/Events/events.args'
#Injectable()
export class UtilsService {
#Inject(PrismaService)
private readonly prisma: PrismaService
private readonly selects = {
'id.title': { id: true, title: true },
'id.fullname': { id: true, fullname: true },
'id.title.attributes': { id: true, title: true, attributes: true },
'id.code.description.attributes': {
id: true,
code: true,
description: true,
attributes: true
}
}
/**
* Get reminders, types of activities, case, client and attendees of an event
* #param {EventBodyDTO} payload Event data
*/
async getEventFields(payload: EventBodyDTO) {
const [activityType, eventCase, client, assistants, reminders] =
await Promise.all([
// Get an activity type by id
this.prisma.parameters.findUnique({
select: this.selects['id.title'],
where: { id: payload.activityType }
}),
// Get a case by id
this.prisma.expedients.findUnique({
where: { id: payload.case },
select: this.selects['id.code.description.attributes']
}),
// Get a person by id
this.prisma.people.findFirst({
select: this.selects['id.fullname'],
where: { isClient: true, id: payload.client }
}),
// Get attendees by id
this.prisma.people.findMany({
select: this.selects['id.fullname'],
where: {
isEmployee: true,
id: { in: payload.assistants }
}
}),
// Get reminders by id
this.prisma.parameters.findMany({
select: this.selects['id.title.attributes'],
where: {
id: { in: payload.reminders }
}
})
])
return {
reminders: reminders,
assistants: assistants,
client: client === null ? {} : client,
case: eventCase === null ? {} : eventCase,
activityType: activityType === null ? {} : activityType
}
/**
* Create filters to filter by customer or event attendees
* #param {EventsArgs} args Arguments to filter
* #returns {Promise<Prisma.EventsFindManyArgs['where']>} Returns an object with filters
*/
async createEventFilters(
args: EventsArgs
): Promise<Prisma.EventsFindManyArgs['where']> {
const filters: Prism.EventsFindManyArgs['where'] = {
userId: args.user
}
// Filter by customer
if (typeof args.client === 'string') {
const clients = await this.prisma.people.findMany({
where: {
isClient: true,
fullname: {
mode: 'insensitive',
contains: args.client
}
},
select: {
id: true,
fullname: true
}
})
filters.OR = []
for (const client of clients) {
filters.OR.push({
client: { equals: client }
})
}
}
// Filter by attendees
if (Array.isArray(args.assistants)) {
const assistants = await this.prisma.people.findMany({
where: {
isEmployee: true,
id: {
in: args.assistants
}
},
select: {
id: true,
fullname: true
}
})
if (!Array.isArray(filters.OR)) {
filters.OR = []
}
filters.OR.push({
assistants: { hasSome: assistants }
})
}
return filters
}
}

How to use Axios in Nest.js to POST params request?

I am beginner in NestJS and I would like to ask question on how to use Axios in NestJs. But the problem is I keep getting error TypeError: Converting circular structure to JSON
I have created an API POST http://localhost:3000/api/create in NestJS and my raw request
Raw input
{
"id":1,
"date":"2022-06-28",
"roster":[
{
"startDate":"2022-06-27",
"weekDay":1,
"session":1,
"sTime":"08:00:00",
"eTime":"10:00:00"
}
]
}
Postman request images
My goal is in create.service.ts file, I want pass the value that I receive in postman and add all values into new API link https://create.com/api/index.php?id=&date=&roster=[].
Expected output : https://create.com/api/index.php?id=1&date=2022-06-27&roster=[{"startDate":"2022-06-27","weekDay":1,"session":1,"sTime":"08:00:00","eTime":"10:00:00"}]
But I receive an error TypeError: Converting circular structure to JSON when I submit my post request
create.service.ts
import { HttpException, Injectable } from '#nestjs/common';
import axios from 'axios';
import { CreateValidator } from './create.validator';
#Injectable()
export class CreateService {
constructor() { }
async create(query: CreateValidator) {
return axios.post(`https://create.com/api/index.php?`, null, { params: query })
.then()
.catch(err => {
throw new HttpException(err.response?.data ?? err.response?.statusText ?? 'Unexpected error.', err.response?.status ?? 400);
});
}
}
create.controller.ts
import { Post, Body } from '#nestjs/common';
import { ApiConsumes, ApiTags } from '#nestjs/swagger';
import { BaseController } from '../base/base.controller';
import { CreateService } from './create.service';
import { CreateValidator } from './create.validator';
#ApiTags('New : Create ')
export class CreateController extends BaseController {
constructor(
private readonly createService: CreateService,
) {
super();
}
#Post('api/create')
#ApiConsumes('application/x-www-form-urlencoded')
async create(#Body() body: CreateValidator) {
const result = await this.createService.create(body);
return {result,};
}
}
create.validator.ts
import { ApiProperty } from '#nestjs/swagger';
import { Transform } from 'class-transformer';
import { IsNotEmpty, isString } from 'class-validator';
export class CreateValidator {
#ApiProperty({type: Number,required: true,})
id: number;
#ApiProperty({type: String,required: true,})
date: Date;
#ApiProperty({type: [Object],})
#Transform((input) => isString(input.value) ? JSON.parse(input.value) : input.value)
#IsNotEmpty({ message: 'IsNotEmpty' })
roster: Array<{
startDate: Date;
weekDay: number;
s_time: string;
e_time: string;
}>;
}
My current coding as below
It turns out that I need to change #ApiProperty({ type : [Object]}) into #ApiProperty({ type : Object }) in my validator file.
create.validator.ts
import { ApiProperty } from '#nestjs/swagger';
import { Transform } from 'class-transformer';
import { IsNotEmpty, isString } from 'class-validator';
export class CreateValidator {
#ApiProperty({type: Number,required: true,})
id: number;
#ApiProperty({type: String,required: true,})
date: Date;
#ApiProperty({type: Object,})
#Transform((input) => isString(input.value) ? JSON.parse(input.value) : input.value)
#IsNotEmpty({ message: 'IsNotEmpty' })
roster: Array<{
startDate: Date;
weekDay: number;
s_time: string;
e_time: string;
}>;
}
Now it's working fine.
Thanks.

React DnD - "Cannot have two HTML5 backends at the same time."

I am trying to make a POC with Rails5, action Cable, React and Rails and React DnD.
The purpose is to make an app like trello but for an recruitment process.
My front is in ReactJS.
I have 3 components, first, the container call "Candidates", this component call 2 "CardBoard" components that call "Card" component.
I user react DnD library for draggable card and droppable CardBoard. when i drop card on cardboard, i use a post call and a websocket(action cable from rails5) for update my state. I don't understand why i have this message after the post call :
Uncaught Error: Cannot have two HTML5 backends at the same time.
at HTML5Backend.setup (eval at <anonymous> (webpack-bundle.self-7b1a342….js?body=1:4175), <anonymous>:87:15)
at DragDropManager.handleRefCountChange (eval at <anonymous> (webpack-bundle.self-7b1a342….js?body=1:3566), <anonymous>:52:22)
at Object.dispatch (eval at <anonymous> (webpack-bundle.self-7b1a342….js?body=1:4931), <anonymous>:186:19)
at HandlerRegistry.addSource (eval at <anonymous> (webpack-bundle.self-7b1a342….js?body=1:3594), <anonymous>:104:18)
at registerSource (eval at <anonymous> (webpack-bundle.self-7b1a342….js?body=1:4294), <anonymous>:9:27)
at DragDropContainer.receiveType (eval at <anonymous> (webpack-bundle.self-7b1a342….js?body=1:1793), <anonymous>:146:32)
at DragDropContainer.receiveProps (eval at <anonymous> (webpack-bundle.self-7b1a342….js?body=1:1793), <anonymous>:135:14)
at new DragDropContainer (eval at <anonymous> (webpack-bundle.self-7b1a342….js?body=1:1793), <anonymous>:102:13)
at eval (eval at <anonymous> (webpack-bundle.self-7b1a342….js?body=1:4399), <anonymous>:295:18)
at measureLifeCyclePerf (eval at <anonymous> (webpack-bundle.self-7b1a342….js?body=1:4399), <anonymous>:75:12)
Candidate.jsx =
import React, { PropTypes } from 'react';
import { DragDropContextProvider } from 'react-dnd';
import HTML5Backend from 'react-dnd-html5-backend';
import CardBoard from './CardBoard.jsx';
export default class Candidates extends React.Component {
constructor(props, _railsContext) {
super(props);
this.state = {
candidates: this.props.candidates
}
this.filterByStatus = this.filterByStatus.bind(this)
}
componentDidMount() {
this.setupSubscription();
}
setupSubscription() {
App.candidate = App.cable.subscriptions.create("CandidateChannel", {
connected: () => {
console.log("User connected !")
},
received: (data) => {
this.setState({ candidates: data.candidates })
},
});
}
render() {
return (
<DragDropContextProvider backend={HTML5Backend}>
<div className="recruitment">
{
["À Rencontrer", "Entretien"].map((status, index) => {
return (
<CardBoard candidates={(this.filterByStatus({status}))} status={status} key={index} />
);
})
}
</div>
</DragDropContextProvider>
);
}
}
CardBoard.jsx =
import React, { PropTypes } from 'react';
import Card from './Card.jsx';
import { DropTarget } from 'react-dnd';
import ItemTypes from './ItemTypes';
const cardTarget = {
drop(props: Props) {
var status = ''
if(props.status == "À Rencontrer") {
status = 'to_book'
} else {
status = 'interview'
}
return { status: status };
},
};
#DropTarget(ItemTypes.CARD, cardTarget, (connect, monitor) => ({
connectDropTarget: connect.dropTarget(),
isOver: monitor.isOver(),
canDrop: monitor.canDrop(),
}))
export default class CardBoard extends React.Component<Props> {
constructor(props, _railsContext) {
super(props);
}
render() {
const { canDrop, isOver, connectDropTarget } = this.props;
const isActive = canDrop && isOver;
return connectDropTarget(
<div className={`${this.props.status} ui cards`}>
<h2>{`${this.props.status} (${this.props.candidates.length})`}</h2>
{
(this.props.candidates).map((candidate, index) => {
return <Card candidate={candidate} key={index} />
})
}
{ isActive?
'Release to drop' : 'drag a card here'
}
</div>
);
}
}
Card.jsx=
import React, { PropTypes } from 'react';
import { DragSource } from 'react-dnd';
import ItemTypes from './ItemTypes';
const cardSource = {
beginDrag(props) {
return {
candidate_id: props.candidate.id,
};
},
endDrag(props, monitor) {
const item = monitor.getItem();
const dropResult = monitor.getDropResult();
if (dropResult) {
console.log(`You dropped ${item.candidate_id} vers ${dropResult.status} !`);
$.post(`/update_status/${item.candidate_id}/${dropResult.status}`);
}
},
};
#DragSource(ItemTypes.CARD, cardSource, (connect, monitor) => ({
connectDragSource: connect.dragSource(),
isDragging: monitor.isDragging(),
}))
export default class Card extends React.Component {
constructor(props, _railsContext) {
super(props);
}
render() {
const { isDragging, connectDragSource } = this.props;
const { name } = this.props;
const opacity = isDragging ? 0 : 1;
var candidate = this.props.candidate;
return (
connectDragSource(
<div className="card" key={candidate.id} style={{opacity}}>
<div className="content">
<div className="header">{`${candidate.first_name} ${candidate.last_name}`}</div>
<div className="description">
{candidate.job_title}
</div>
<span className="right floated">
<i className="heart outline like icon"></i>
{candidate.average_rate}
</span>
</div>
</div>
)
);
}
}
for better comprehension, here a gif of my feature and his bug :
feature with bug
here my github repo with all code
Just try to make the context of HTML5Backend a singleton. You can check the codes at:
https://github.com/react-dnd/react-dnd/issues/186
https://github.com/react-dnd/react-dnd/issues/708
I faced with similar issue and found workaround by moving
<DragDropContextProvider></DragDropContextProvider>
to the topmost react component.
Structure before:
App
Component1
Component2
...
ComponentX with render(<DragDropContextProvider>...<DragDropContextProvider>)
Structure after:
App with render(<DragDropContextProvider>...<DragDropContextProvider>)
Component1
Component2
...
ComponentX
Supposing App is loaded only once and HTML5 backend is not replicated.
You can either create a new file and import DragDropContext where you need it:
import HTML5 from 'react-dnd-html5-backend';
import {DragDropContext} from 'react-dnd';
export default DragDropContext(HTML5);
Source: https://github.com/react-dnd/react-dnd/issues/708#issuecomment-309259695
Or using Hooks:
import { DndProvider, createDndContext } from "react-dnd";
import HTML5Backend from "react-dnd-html5-backend";
import React, { useRef } from "react";
const RNDContext = createDndContext(HTML5Backend);
function useDNDProviderElement(props) {
const manager = useRef(RNDContext);
if (!props.children) return null;
return <DndProvider manager={manager.current.dragDropManager}>{props.children}</DndProvider>;
}
export default function DragAndDrop(props) {
const DNDElement = useDNDProviderElement(props);
return <React.Fragment>{DNDElement}</React.Fragment>;
}
Use:
import DragAndDrop from "../some/path/DragAndDrop";
export default function MyComp(props){
return <DragAndDrop>....<DragAndDrop/>
}
Source: https://github.com/react-dnd/react-dnd/issues/186#issuecomment-561631584
If you use BrowserRouter then move the DragDropContextProvider out of BrowserRouter:
Source: https://github.com/react-dnd/react-dnd/issues/186#issuecomment-453990887
DndProvider has a options prop in where you can set rootElement which bounds DnD to that specified context, and unfortunately it isn't documented well. This approach solved all my issues, as I had other component which was using DnD and they were out of my boundary and I wasn't able to make HTML5Backend Singleton.
I tried this approach with "react-dnd": "^14.0.2"
const myFirstId = 'first-DnD-Containier';
const mySecondId = 'second-DnD-Containier';
export const DndWrapper = React.memo((props) => {
const [context, setContext] = useState(null);
useEffect(() => {
setContext(document.getElementById(props.id))
},[props.id])
return context ? (
<DndProvider backend={HTML5Backend} options={{ rootElement: context}}>
{props.children}
</DndProvider>
) : null;
});
export default function App() {
return (
<div>
<div id={myFirstId}>
<DndWrapper id={myFirstId}>
<MyOtherComponents />
</DndWrapper>
</div>
<div id={mySecondId}>
<DndWrapper id={mySecondId}>
<MyOtherComponents />
</DndWrapper>
</div>
</div>
);
}
P.S. Make sure by the time you call document.getElementById the DOM exist with ids.
Move the DragDropContextProvider out of BrowserRouter.
import { BrowserRouter as Router } from 'react-router-dom';
import { DndProvider } from 'react-dnd';
<DndProvider>
<Router>
<App />
</Router>
</DndProvider>

How can I use props to auto-populate editable redux-form fields in React?

I'm new to React so I've tried to show as much code as possible here to hopefully figure this out! Basically I just want to fill form fields with properties from an object that I fetched from another API. The object is stored in the autoFill reducer. For example, I would like to fill an input with autoFill.volumeInfo.title, where the user can change the value before submitting if they want.
I used mapDispatchtoProps from the autoFill action creator, but this.props.autoFill is still appearing as undefined in the FillForm component. I'm also confused about how to then use props again to submit the form. Thanks!
My reducer:
import { AUTO_FILL } from '../actions/index';
export default function(state = null, action) {
switch(action.type) {
case AUTO_FILL:
return action.payload;
}
return state;
}
Action creator:
export const AUTO_FILL = 'AUTO_FILL';
export function autoFill(data) {
return {
type: AUTO_FILL,
payload: data
}
}
Calling the autoFill action creator:
class SelectBook extends Component {
render() {
return (
....
<button
className="btn btn-primary"
onClick={() => this.props.autoFill(this.props.result)}>
Next
</button>
);
}
}
....
function mapDispatchToProps(dispatch) {
return bindActionCreators({ autoFill }, dispatch);
}
export default connect(mapStateToProps, mapDispatchToProps)(SelectBook);
And here is the actual Form where the issues lie:
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { reduxForm } from 'redux-form';
import { createBook } from '../actions/index;
class FillForm extends Component {
constructor(props) {
super(props);
this.state = {value: ''};
this.handleChange = this.handleChange.bind(this);
}
onSubmit(props) {
this.props.createBook(props)
}
handleChange(event) {
this.setState({value: event.target.value});
}
render() {
const { fields: { title }, handleSubmit } = this.props;
return (
<form {...initialValues} onSubmit={handleSubmit(this.onSubmit.bind(this))}>
<input type="text" className="form-control" name="title" {...title} />
<button type="submit">Submit</button>
</form>
)
}
export default reduxForm({
form: 'AutoForm',
fields: ['title']
},
state => ({
initialValues: {
title: state.autoFill.volumeInfo.title
}
}), {createBook})(FillForm)
I think you're mixing up connect and reduxForm decorators in the actual form component. Currently your code looks like this (annotations added by me):
export default reduxForm({
// redux form options
form: 'AutoForm',
fields: ['title']
},
// is this supposed to be mapStateToProps?
state => ({
initialValues: {
title: state.autoFill.volumeInfo.title
}
}),
/// and is this mapDispatchToProps?
{createBook})(FillForm)
If this is the case, then the fix should be as simple as using the connect decorator as it should be (I also recommend separating this connect props to their own variables to minimize confusions like this):
const mapStateToProps = state => ({
initialValues: {
title: state.autoFill.volumeInfo.title
}
})
const mapDispatchToProps = { createBook }
export default connect(mapStateToProps, mapDispatchToProps)(
reduxForm({ form: 'AutoForm', fields: ['title'] })(FillForm)
)
Hope this helps!

Ionic 2 HTTP request not working - Angular 2

Hi I'm trying to do a simple Http GET request, but can't get it to work in ionic v2 Beta...
here is my app.js:
import {App, Platform} from 'ionic-angular';
import {TabsPage} from './pages/tabs/tabs';
import {HTTP_BINDINGS} from 'angular2/http';
#App({
template: '<ion-nav [root]="rootPage"></ion-nav>',
providers: [HTTP_BINDINGS],
config: {} // http://ionicframework.com/docs/v2/api/config/Config/
})
export class MyApp {
static get parameters() {
return [[Platform]];
}
constructor(platform) {
this.rootPage = TabsPage;
platform.ready().then(() => {
});
}
}
and this is my page1.js:
import {Page} from 'ionic-angular';
import {Http} from 'angular2/http';
#Page({
templateUrl: 'build/pages/page1/page1.html'
})
export class Page1 {
constructor(http:Http) {
this.mget = http.get("https://httpbin.org/ip")
.subscribe(data => {
var alert = Alert.create({
title: "Your IP Address",
subTitle: data.json().origin,
buttons: ["close"]
});
this.nav.present(alert);
}, error => {
console.log(JSON.stringify(error.json()));
});
}
}
When adding http:Http to the constructor -> constructor(http:Http) the whole app goes blank in browser...
And I get an error in Console:
Error: Cannot find module "../page1/page1"
I've also tried this in Page1.js:
export class Page1 {
constructor() {
}
makeGetRequest() {
this.http.get("https://httpbin.org/ip")
.subscribe(data => {
var alert = Alert.create({
title: "Your IP Address",
subTitle: data.json().origin,
buttons: ["close"]
});
this.nav.present(alert);
}, error => {
console.log(JSON.stringify(error.json()));
console.log('yolo')
alert('hello');
});
}
}
and then call makeGetRequest() on (click) in page1.html
but it returns these exeptions:
EXCEPTION: Error during evaluation of "click"
ORIGINAL EXCEPTION: TypeError: this.http is undefined
please help!
:)
-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
THIS IS THE SOLUTION:
page1.js:
import {Page} from 'ionic-angular';
import {Http} from 'angular2/http';
#Page({
templateUrl: 'build/pages/page1/page1.html'
})
export class Page1 {
static get parameters(){
return [Http];
}
constructor(http) {
this.http = http;
this.mget = this.http.get("https://httpbin.org/ip")
.subscribe(data => {
console.log(data);
}, error => {
console.log('faild');
});
}
}
app.js:
import {App, Platform} from 'ionic-angular';
import {TabsPage} from './pages/tabs/tabs';
import { HTTP_PROVIDERS } from 'angular2/http';
#App({
template: '<ion-nav [root]="rootPage"></ion-nav>',
providers: [HTTP_PROVIDERS],
config: {} // http://ionicframework.com/docs/v2/api/config/Config/
})
export class MyApp {
static get parameters() {
return [[Platform]];
}
constructor(platform) {
this.rootPage = TabsPage;
platform.ready().then(() => {
});
}
}
Please try this
export class Page1 {
static get parameters(){
return [Http];
}
constructor(http) {
this.http = http;
this.mget = this.http.get("https://httpbin.org/ip")
.subscribe(data => {
var alert = Alert.create({
title: "Your IP Address",
subTitle: data.json().origin,
buttons: ["close"]
});
this.nav.present(alert);
}, error => {
console.log(JSON.stringify(error.json()));
});
}
}
I would recommend you to write the get request inside a separate service and inject it in your page.
Also have a look at this - http://tphangout.com/?p=113
Detailed and simple instructions are given there for making a simple GET request from an Ionic 2 app.
I believe you need to
import { HTTP_PROVIDERS } from 'angular2/http';
in your app.js instead of HTTP_BINDINGS and change providers: [HTTP_BINDINGS] to providers: [HTTP_PROVIDERS]
See Angular2 docs