Friday, 29 June 2018
react + mongoDB reference
reference:
http://mern.io/
https://github.com/Hashnode/mern-starter
http://mern.io/documentation.html
tutorial
https://www.youtube.com/watch?v=rpJO0T08Bnc&t=3199s
graphql-yoga
https://github.com/prismagraphql/graphql-yoga
graphql schema
https://graphql.org/learn/schema/
mongoose
http://mongoosejs.com/docs/index.html
apollo
https://www.apollographql.com/docs/react/essentials/get-started.html
apollo auto update cache
https://www.apollographql.com/docs/angular/features/cache-updates.html#directAccess
material-ui
https://material-ui.com/
Wednesday, 27 June 2018
Tuesday, 26 June 2018
Monday, 25 June 2018
MongoDB tutorial
https://www.youtube.com/playlist?list=PL6gx4Cwl9DGDQ5DrbIl20Zu9hx1IjeVhO
{"age": {$gt:30}} gt> lt< gte>= lte<= ne!=
db.collectionName.getIndexes()
db.collectionName.droptIndex({"age":1})
$group:{
_id: "$groupColumn",
total: {$sum: 1},
avg: {$avg: "avgColumn"},
max: {$max: "maxColumn"
}
})
json generator
https://next.json-generator.com/
mongoDB community
https://www.mongodb.com/download-center?jmp=nav#community
mongoDB compass
https://www.mongodb.com/download-center#compass
Studio 3T
https://studio3t.com/download-thank-you/?OS=win64
command
switch to/ create db
use xxxdrop database
db.dropDatabase()insert
db.collectionName.insert(json)
db.collectionName.insert([jsons])
show collections
show collections
search
db.collectionName.find(json criteria)
db.collectionName.findOne()
db.collectionName.find(
json criteria,
{"name":1, _id:0} display name, not _id
)
db.collectionName.find(
json criteria,
{"name":1, _id:0} display name, not _id
)
db.collectionName.find().limit(3)
db.collectionName.find().skip(2)
db.collectionName.find().skip(2)
delete
db.collectionName.remove(json criteria)
update
db.collectionName.update(json criteria, json obj)
json criteria
{"position":"defenders", "age":21}
{
$or:[
{"position": "left wing"},
{"position": "right wing"}
]
}
index
db.collectionName.find(json critera),explain("executionStats")
db.collectionName.ensureIndex({"age":1})db.collectionName.getIndexes()
db.collectionName.droptIndex({"age":1})
aggregation and groups
db.collectionName.aggregate({$group:{
_id: "$groupColumn",
total: {$sum: 1},
avg: {$avg: "avgColumn"},
max: {$max: "maxColumn"
}
})
json generator
https://next.json-generator.com/
mongoDB community
https://www.mongodb.com/download-center?jmp=nav#community
mongoDB compass
https://www.mongodb.com/download-center#compass
Studio 3T
https://studio3t.com/download-thank-you/?OS=win64
Sunday, 24 June 2018
react + redux schedule
project link: http://chuanshuoge1.github.io/react-redux-schedule
Index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
import { Provider } from "react-redux";
import store from "./store";
import 'bootstrap/dist/css/bootstrap.min.css';
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>, document.getElementById('root'));
registerServiceWorker();
---------------------------------------------------------------------------------
App.js
import React, { Component } from 'react';
import { connect } from 'react-redux';
import './App.css';
import AddForm from './forms/add';
import DeleteForm from './forms/delete';
import UpdateForm from './forms/update'
import { display_rawSchedules } from './quickFunctions.js';
class App extends Component {
render() {
return (
<div>
{display_rawSchedules(this.props.schedules)}
<AddForm />
<DeleteForm schedules={this.props.schedules} />
<UpdateForm schedules={this.props.schedules} />
</div>
);
}
}
export default connect(
(store) => {
return {
schedules: store.schedules.schedules,
};
}
)(App);
store.js
import { applyMiddleware, createStore } from 'redux';
import logger from 'redux-logger';
import thunk from 'redux-thunk';
import promiseMiddleware from 'redux-promise-middleware';
import reducer from "./reducers";
const middleware = applyMiddleware(promiseMiddleware(), thunk, logger);
export default createStore(reducer, middleware);
------------------------------------------------------------------------------
quickFunctions.js
import React from 'react';
export const display_rawSchedules = (data) => {
const scheduleView = data.map((item, index) => {
const matchView = data[index].matches.map((item2, index2) =>
<div key={index2}>
{"{"}
home: {item2.home}, away: {item2.away},
home score: {item2.homeScore}, away score: {item2.awayScore}
{"}, "}
</div>
);
return (<div key={index}>
date: {item.date.toDateString()}<br />
matches: {matchView}<br />
</div>);
})
return (<div>{scheduleView}</div>);
}
export const dateToString = (date) => {
const year = date.getFullYear().toString();
const month = date.getMonth() + 1;
const month0 = month < 10 ? '0' + month.toString() : month.toString();
const day = date.getDate();
const day0 = day < 10 ? '0' + day.toString() : day.toString();
const newDate = year + '-' + month0 + '-' + day0;
return newDate;
};
export const stringToDate = (input_string) => {
const year_month_day = input_string.split('-');
const year = parseInt(year_month_day[0]);
const month = parseInt(year_month_day[1]) - 1;
const day = parseInt(year_month_day[2]);
return new Date(year, month, day);
}
----------------------------------------------------------------------
actions/scheduleAction.js
export function addSchedule(form) {
return {
type: "add_schedule",
payload: form
}
}
export function deleteAll(schedule_index) {
return {
type: "delete_all",
payload: schedule_index
}
}
export function deleteSingle(schedule_index, match_index) {
return {
type: "delete_single",
payload: {
scheduleIndex: schedule_index,
matchIndex: match_index,
}
}
}
export function updateSchedule(form, schedule_index, match_index) {
return {
type: "update_schedule",
payload: {
form: form,
scheduleIndex: schedule_index,
matchIndex: match_index,
}
}
}
--------------------------------------------------------------------
reducers/index.js
import { combineReducers } from 'redux';
import schedules from "./scheduleReducer";
export default combineReducers(
{
schedules
})
-------------------------------------------------------
reducers/scheduleReducer.js
import { stringToDate, dateToString } from '../quickFunctions'
export default function reducer(
state = {
schedules: [
{
date: new Date(2018, 4, 22),
matches: [
{ home: "santos", away: "real garcilaso", homeScore: 0, awayScore: 0 },
{ home: "atletico nacional", away: "colo colo", homeScore: 0, awayScore: 0 },
{ home: "corinthians", away: "millonarios", homeScore: 0, awayScore: 1 },
{ home: "independiente", away: "deportivolara", homeScore: 2, awayScore: 0 },
]
},
{
date: new Date(2018, 4, 21),
matches: [
{ home: "toronto fc", away: "fc dallas", homeScore: 0, awayScore: 2 },
{ home: "houston dynamo", away: "new york city fc", homeScore: 2, awayScore: 1 },
{ home: "portland thorns fc", away: "utah royals fc", homeScore: 2, awayScore: 1 },
{ home: "los angeles galaxy", away: "san joes earthquakes", homeScore: 0, awayScore: 0 },
]
},
{
date: new Date(2018, 5, 4),
matches: [
{ home: "thailand", away: "china pr", homeScore: 0, awayScore: 1 },
{ home: "austria", away: "germany", homeScore: 3, awayScore: 1 },
{ home: "england", away: "nigeria", homeScore: 1, awayScore: 0 },
{ home: "sweden", away: "denmark", homeScore: 0, awayScore: 0 },
]
},
{
date: new Date(2018, 4, 28),
matches: [
{ home: "brazil", away: "croatia", homeScore: 2, awayScore: 0 },
{ home: "costa rica", away: "northern ireland", homeScore: 3, awayScore: 0 },
{ home: "saudi arabia", away: "peru", homeScore: 0, awayScore: 3 },
{ home: "bahia", away: "gremio", homeScore: 0, awayScore: 1 },
]
},
],
activeTab: "Monday",
dateFilter: "",
},
action
) {
switch (action.type) {
case "add_schedule": {
const newMatch = {
home: action.payload.home,
away: action.payload.away,
homeScore: action.payload.homeScore,
awayScore: action.payload.awayScore,
};
const newSchedules = [...state.schedules];
const findDate_index = newSchedules.findIndex(x => dateToString(x.date) === action.payload.date);
//add to existing schedule
if (findDate_index >= 0) {
newSchedules[findDate_index].matches.push(newMatch);
}
//create new schedule
else {
const newSchedule =
{
date: stringToDate(action.payload.date),
matches: [
newMatch,
]
};
newSchedules.push(newSchedule);
}
return { ...state, schedules: newSchedules }
}
case "delete_all": {
const newSchedules = [...state.schedules];
newSchedules.splice(action.payload, 1);
return { ...state, schedules: newSchedules }
}
case "delete_single": {
const newSchedules = [...state.schedules];
newSchedules[action.payload.scheduleIndex].
matches.splice(action.payload.matchIndex, 1);
return { ...state, schedules: newSchedules }
}
case "update_schedule": {
const newSchedules = [...state.schedules];
newSchedules[action.payload.scheduleIndex].
matches[action.payload.matchIndex] = {
home: action.payload.form.home,
away: action.payload.form.away,
homeScore: action.payload.form.homeScore,
awayScore: action.payload.form.awayScore,
}
return { ...state, schedules: newSchedules }
}
default:
break;
}
return state;
}
-------------------------------------------------------------------------------
forms/add.jsimport React, { Component } from 'react';
import { Button, Form, FormGroup, Input } from 'reactstrap';
import { stringToDate } from '../quickFunctions.js';
import { connect } from 'react-redux';
import { addSchedule } from '../actions/scheduleAction';
import '../App.css';
export class AddForm extends Component {
constructor(props) {
super(props);
this.state = {
date: "",
home: "",
away: "",
homeScore: 0,
awayScore: 0,
status: "",
};
}
handle_submit(e) {
if (this.state.home === "" || this.state.away === "" || this.state.date === "") {
return false;
}
else {
const formData = {
date: this.state.date,
home: this.state.home,
away: this.state.away,
homeScore: this.state.homeScore,
awayScore: this.state.awayScore,
};
this.props.dispatch(addSchedule(formData));
}
e.preventDefault();
const messageStatus = "successfully added to " + stringToDate(this.state.date).toDateString();
this.setState({ status: messageStatus });
}
render() {
return (
<div className="my-schedule-form-add">
<h4>Add Schedule <span className="my-status">{this.state.status}</span></h4>
<Form inline onSubmit={(e) => this.handle_submit(e)}>
<FormGroup >
<Input type="date" bsSize="sm" name="matchDate" placeholder="Match Date" required="required"
onChange={(e) => this.setState({ date: e.target.value })} />
</FormGroup>
<FormGroup >
<Input bsSize="sm" placeholder="Home Team" required="required"
onChange={(e) => this.setState({ home: e.target.value })} />
</FormGroup>
<FormGroup >
<Input bsSize="sm" placeholder="Away Team" required="required"
onChange={(e) => this.setState({ away: e.target.value })} />
</FormGroup>
<FormGroup >
<Input type="number" bsSize="sm" placeholder="Home Score"
onChange={(e) => this.setState({ homeScore: e.target.value })} />
</FormGroup>
<FormGroup >
<Input type="number" bsSize="sm" placeholder="Away Score"
onChange={(e) => this.setState({ awayScore: e.target.value })} />
</FormGroup>
<Button size="sm" type="submit" onClick={() => this.setState({ status: "" })}> Submit</Button>
</Form>
</div>
);
}
}
export default connect(
(store) => {
return {
schedules: store.schedules.schedules,
};
}
)(AddForm);
------------------------------------------------------------------
forms/delete.js
import React, { Component } from 'react';
import { Button, Input, Row, Col } from 'reactstrap';
import { dateToString } from '../quickFunctions.js';
import { connect } from 'react-redux';
import { deleteAll, deleteSingle } from '../actions/scheduleAction.js';
import '../App.css';
export class DeleteForm extends Component {
constructor(props) {
super(props);
this.state = {
selectedMatch: 0,
selectedDate: "",
dateDisable: false,
matchDisable: false,
status:"",
};
}
handle_selectDate(e) {
this.setState({
dateDisable: true,
selectedDate: e.target.value,
});
}
handle_selectMatch(e) {
this.setState({
matchDisable: true,
selectedMatch: parseInt(e.target.value.split(' ')[0].slice(1)) - 1,
});
}
handle_deleteSingle() {
const selectedSchedule_index = this.props.schedules.findIndex(
x => dateToString(x.date) === this.state.selectedDate);
this.props.dispatch(
deleteSingle(selectedSchedule_index, this.state.selectedMatch));
const messageStatus = "deleted " + this.state.selectedDate + " match " +
(this.state.selectedMatch + 1).toString();
this.setState({ status: messageStatus });
}
handle_deleteAll() {
const selectedSchedule_index = this.props.schedules.findIndex(
x => dateToString(x.date) === this.state.selectedDate);
this.props.dispatch(deleteAll(selectedSchedule_index));
const messageStatus = "deleted " + this.state.selectedDate;
this.setState({ status: messageStatus });
}
render() {
const dateOptions = this.props.schedules.
map((item, index) => {
const dateString = dateToString(item.date);
return (
<option key={dateString}>{dateString}</option>);
}).
sort((a, b) => {
return a.key.localeCompare(b.key)
});
dateOptions.unshift(<option key={-1} disabled={this.state.dateDisable}>
select date</option>);
const selectedSchedule_index = this.props.schedules.findIndex(
x => dateToString(x.date) === this.state.selectedDate);
const matchOptions = selectedSchedule_index >= 0 ?
this.props.schedules[selectedSchedule_index].matches.
map((item, index) =>
<option key={index}>#{index + 1} {item.home} vs {item.away}</option>
)
: [];
matchOptions.unshift(<option key={-1} disabled={this.state.matchDisable}>
select match</option>);
return (
<div className="my-schedule-form-delete">
<h4>Delete Schedule <span className="my-status">{this.state.status}</span></h4>
<Row>
<Col xs="3">
<Input type="select" bsSize="sm"
onChange={(e) => this.handle_selectDate(e)}>
{dateOptions}</Input>
</Col>
<Col xs="5">
<Input type="select" bsSize="sm" disabled={!this.state.dateDisable}
onChange={(e) => this.handle_selectMatch(e)}>
{matchOptions}</Input>
</Col>
<Col xs="2">
<Button size="sm" disabled={!this.state.matchDisable}
onClick={() => this.handle_deleteSingle()}>
Delete single</Button>
</Col>
<Col xs="2">
<Button size="sm" disabled={!this.state.dateDisable}
onClick={() => this.handle_deleteAll()}>
Delete all</Button>
</Col>
</Row>
</div>
);
}
}
export default connect(
(store) => {
return {
schedules: store.schedules.schedules,
};
}
)(DeleteForm);
------------------------------------------------------------------
forms/update.js
import React, { Component } from 'react';
import { Button, Form, FormGroup, Input, Row, Col } from 'reactstrap';
import { dateToString, stringToDate } from '../quickFunctions.js';
import { connect } from 'react-redux';
import { updateSchedule} from '../actions/scheduleAction.js';
import '../App.css';
export class UpdateForm extends Component {
constructor(props) {
super(props);
this.state = {
selectedMatch: 0,
selectedDate: "",
dateDisable: false,
matchDisable: false,
home: "Home Team",
away: "Away Team",
homeScore: 0,
awayScore: 0,
status:"select date -> match -> update input -> submit",
};
}
handle_selectDate(e) {
this.setState({
dateDisable: true,
selectedDate: e.target.value,
});
}
handle_selectMatch(e) {
const matchIndex = parseInt(e.target.value.split(' ')[0].slice(1)) - 1;
const scheduleIndex = this.props.schedules.findIndex(
x => dateToString(x.date) === this.state.selectedDate);
const matchSelected = this.props.schedules[scheduleIndex].matches[matchIndex];
this.setState({
matchDisable: true,
selectedMatch: matchIndex,
home: matchSelected.home,
away: matchSelected.away,
homeScore: matchSelected.homeScore,
awayScore: matchSelected.awayScore,
});
}
handle_submit(e) {
if (this.state.home === "" || this.state.away === "") {
return false;
}
else {
const formData = {
home: this.state.home,
away: this.state.away,
homeScore: this.state.homeScore,
awayScore: this.state.awayScore,
};
const selectedSchedule_index = this.props.schedules.findIndex(
x => dateToString(x.date) === this.state.selectedDate);
this.props.dispatch(updateSchedule(
formData,
selectedSchedule_index,
this.state.selectedMatch,
));
}
e.preventDefault();
const messageStatus = "updated " + this.state.selectedDate + " match " +
(this.state.selectedMatch+1).toString();
this.setState({ status: messageStatus });
}
render() {
const dateOptions = this.props.schedules.
map((item, index) => {
const dateString = dateToString(item.date);
return (
<option key={dateString}>{dateString}</option>);
}).
sort((a, b) => {
return a.key.localeCompare(b.key)
});
dateOptions.unshift(<option key={-1} disabled={this.state.dateDisable}>
select date</option>);
const selectedSchedule_index = this.props.schedules.findIndex(
x => dateToString(x.date) === this.state.selectedDate);
const matchOptions = selectedSchedule_index >= 0 ?
this.props.schedules[selectedSchedule_index].matches.
map((item, index) =>
<option key={index}>#{index + 1} {item.home} vs {item.away}</option>
)
: [];
matchOptions.unshift(<option key={-1} disabled={this.state.matchDisable}>
select match</option>);
return (
<div className="my-schedule-form-update">
<h4>update Schedule <span className="my-status">{this.state.status}</span></h4>
<Row>
<Col xs="3">
<Input type="select" bsSize="sm"
onChange={(e) => this.handle_selectDate(e)}>
{dateOptions}</Input>
</Col>
<Col xs="5">
<Input type="select" bsSize="sm" disabled={!this.state.dateDisable}
onChange={(e) => this.handle_selectMatch(e)}>
{matchOptions}</Input>
</Col>
</Row>
<Form inline onSubmit={(e) => this.handle_submit(e)} >
<FormGroup >
<Input bsSize="sm" placeholder={this.state.home}
onChange={(e) => this.setState({ home: e.target.value })} />
</FormGroup>
<FormGroup >
<Input bsSize="sm" placeholder={this.state.away}
onChange={(e) => this.setState({ away: e.target.value })} />
</FormGroup>
<FormGroup >
<span id="update_homeScore">
<span className="my-tooltip">home score</span>
<Input type="number" bsSize="sm" placeholder={this.state.homeScore}
onChange={(e) => e.target.value !== "" ? this.setState({ homeScore: e.target.value }) : null}
disabled={this.state.disable_input} />
</span>
</FormGroup>
<FormGroup >
<span id="update_awayScore">
<span className="my-tooltip">away score</span>
<Input type="number" bsSize="sm" placeholder={this.state.awayScore}
onChange={(e) => e.target.value !== "" ? this.setState({ awayScore: e.target.value }) : null}
disabled={this.state.disable_input} />
</span>
</FormGroup>
<Button size="sm" type="submit" disabled={!this.state.matchDisable}
onClick={() => this.setState({ status: "select date -> match -> update input -> submit" })}>
Submit</Button>
</Form>
</div>
);
}
}
export default connect(
(store) => {
return {
schedules: store.schedules.schedules,
};
}
)(UpdateForm);
----------------------------------------------------------
reference:
http://chuanshuoge2.blogspot.com/search?q=react-redux
http://chuanshuoge2.blogspot.com/search?q=react+schedule
http://chuanshuoge2.blogspot.com/search?q=react+git
http://chuanshuoge2.blogspot.com/2018/06/react-redux-schedule.html
Wednesday, 20 June 2018
Monday, 18 June 2018
Sunday, 17 June 2018
reactstrap Carousel card
project site: http://chuanshuoge1.github.io/reactstrap
reference:
https://reactstrap.github.io/components/carousel/
https://stackoverflow.com/questions/36862334/get-viewport-window-height-in-reactjs
https://stackoverflow.com/questions/39066671/react-update-component-margin-top-with-jquery
js
import React, { Component } from 'react';
import {
Carousel,
CarouselItem,
CarouselControl,
CarouselIndicators,
CarouselCaption,
Row, Col
} from 'reactstrap';
import {
Card, CardImg, CardText, CardBody, CardLink,
CardTitle, CardSubtitle
} from 'reactstrap';
export const Home = () => (
<div>
<h1>Welcome to the Bob's Website!</h1>
<MyCarousel />
{MyCard()}
</div>
)
const items = [
{
id: 1,
altText: '',
caption: '',
src: 'https://github.com/chuanshuoge1/reactstrap/blob/gh-pages/image/1.png?raw=true'
},
{
id: 2,
altText: '',
caption: '',
src: 'https://github.com/chuanshuoge1/reactstrap/blob/gh-pages/image/2.png?raw=true'
},
{
id: 3,
altText: '',
caption: '',
src: 'https://github.com/chuanshuoge1/reactstrap/blob/gh-pages/image/3.png?raw=true'
}
];
class MyCarousel extends Component {
constructor(props) {
super(props);
this.state = { activeIndex: 0 };
this.next = this.next.bind(this);
this.previous = this.previous.bind(this);
this.goToIndex = this.goToIndex.bind(this);
this.onExiting = this.onExiting.bind(this);
this.onExited = this.onExited.bind(this);
}
onExiting() {
this.animating = true;
}
onExited() {
this.animating = false;
}
next() {
if (this.animating) return;
const nextIndex = this.state.activeIndex === items.length - 1 ? 0 : this.state.activeIndex + 1;
this.setState({ activeIndex: nextIndex });
}
previous() {
if (this.animating) return;
const nextIndex = this.state.activeIndex === 0 ? items.length - 1 : this.state.activeIndex - 1;
this.setState({ activeIndex: nextIndex });
}
goToIndex(newIndex) {
if (this.animating) return;
this.setState({ activeIndex: newIndex });
}
render() {
const { activeIndex } = this.state;
const marginLeft = (window.innerWidth / 2 - 150).toString() + 'px';
const slides = items.map((item) => {
return (
<CarouselItem
className="my-Carousel"
tag="div"
key={item.id}
onExiting={this.onExiting}
onExited={this.onExited}
>
<a href="https://www.tsn.ca/soccer" target="_blank">
<img className="my-CarouselImage" style={{ marginLeft: marginLeft }}
src={item.src} alt={item.altText} />
</a>
</CarouselItem>
);
});
return (
<div>
<Carousel
activeIndex={activeIndex}
next={this.next}
previous={this.previous}
>
<CarouselIndicators items={items} activeIndex={activeIndex} onClickHandler={this.goToIndex} />
{slides}
<CarouselControl direction="prev" directionText="Previous" onClickHandler={this.previous} />
<CarouselControl direction="next" directionText="Next" onClickHandler={this.next} />
</Carousel>
</div>
);
}
}
const MyCard = () => {
return (
<div>
<Row>
<Col sm={{ size: 6, offset: 3 }}>
<Card style={{ backgroundColor: 'lightgrey', borderColor: '#555' }}>
<CardBody>
<CardTitle>Bob's Blog</CardTitle>
</CardBody>
<img src="https://github.com/chuanshuoge1/reactstrap/blob/gh-pages/image/4.png?raw=true" alt="blog" />
<CardBody>
<CardText>Blog links:</CardText>
<CardLink href="http://chuanshuoge2.blogspot.com/">blog1</CardLink>
<CardLink href="http://chuanshuoge1.blogspot.com/">blog2</CardLink>
</CardBody>
</Card>
</Col>
</Row>
</div>
);
};
-------------------------------------------------
css
.my-Carousel {
max-width: 100%;
height:300px;
background: black;
}
.my-CarouselImage {
height:300px;
}
reference:
https://reactstrap.github.io/components/carousel/
https://stackoverflow.com/questions/36862334/get-viewport-window-height-in-reactjs
https://stackoverflow.com/questions/39066671/react-update-component-margin-top-with-jquery
Saturday, 16 June 2018
react axios + aspcore webapi
axios get data from webapi
axios post to webapi, items are added
axios delete request to webapi, item with id '2' is deleted
axios update request to webapi, item id '3' sam->Sam true->false
axios try to delete and update item id '4', item not found on webapi, error response
stop webapi, axios receives network error response
webapi header
webapi
webapi startup.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.EntityFrameworkCore;
using webApi.Models;
namespace webApi
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy("AllowAllOrigins", builder => builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
});
services.AddDbContext<Context>(opt =>
opt.UseInMemoryDatabase("MyApiDb"));
services.AddMvc();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseCors("AllowAllOrigins");
app.UseMvc();
}
}
}
-----------------------------------------------------------------------------
webapi ItemsController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using webApi.Models;
namespace webApi.Controllers
{
[Produces("application/json")]
[Route("api/values")]
[EnableCors("AllowAllOrigins")]
public class ItemsController : Controller
{
private readonly Context _context;
public ItemsController(Context context)
{
_context = context;
if (_context.Items.Count() == 0)
{
_context.Items.Add(new Item
{
Name = "bob",
IsComplete = true,
});
_context.SaveChanges();
}
}
// GET: api/values
[HttpGet]
public IEnumerable<Item> GetItems()
{
return _context.Items.ToList();
}
// GET: api/values/5
[HttpGet("{id}")]
public async Task<IActionResult> GetItem([FromRoute] int id)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var item = await _context.Items.SingleOrDefaultAsync(m => m.Id == id);
if (item == null)
{
return NotFound();
}
return Ok(item);
}
// PUT: api/values/5
[HttpPut("{id}")]
public async Task<IActionResult> PutItem([FromRoute] int id, [FromBody] Item item)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
if (id != item.Id)
{
return BadRequest();
}
_context.Entry(item).State = EntityState.Modified;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!ItemExists(id))
{
return NotFound();
}
else
{
throw;
}
}
return Ok();
}
// POST: api/values
[HttpPost]
public async Task<IActionResult> PostItem([FromBody] Item item)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
_context.Items.Add(item);
await _context.SaveChangesAsync();
return CreatedAtAction("GetItem", new { id = item.Id }, item);
}
// DELETE: api/values/5
[HttpDelete("{id}")]
public async Task<IActionResult> DeleteItem([FromRoute] int id)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var item = await _context.Items.SingleOrDefaultAsync(m => m.Id == id);
if (item == null)
{
return NotFound();
}
_context.Items.Remove(item);
await _context.SaveChangesAsync();
return Ok(item);
}
private bool ItemExists(int id)
{
return _context.Items.Any(e => e.Id == id);
}
}
}
-------------------------------------------------------------------------
webapi context.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
namespace webApi.Models
{
public class Context:DbContext
{
public Context(DbContextOptions<Context> options)
: base(options)
{
}
public DbSet<Item> Items { get; set; }
}
}
----------------------------------------------------------
webapi Item.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace webApi.Models
{
public class Item
{
public int Id { get; set; }
public string Name { get; set; }
public bool IsComplete { get; set; }
}
}
---------------------------------------------------------
react app.js
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import axios from 'axios';
import { Button, Form, FormGroup, Input } from 'reactstrap';
class App extends Component {
constructor(props) {
super(props);
this.state = {
items: [],
name_input: "",
name_update: "",
iscomplete_input: "",
iscomplete_update:"",
delete_id: -1,
update_id: -1,
get_status: "",
add_status: "",
delete_status: "",
update_status: "",
}
}
handle_getAll() {
axios.get(myUrl)
.then(res => {
const Data = res.data;
this.setState({ items: Data });
res.statusText ? this.setState({ get_status: res.statusText }) : null;
})
.catch(error => {
this.setState({ get_status: error.message })
});
}
handle_post(e) {
e.preventDefault();
const name = this.state.name_input;
const complete = this.state.iscomplete_input === "true" ? true : false;
if (name !== "") {
axios.post(myUrl, { name: name, isComplete: complete })
.then(res => {
console.log(res);
console.log(res.data);
res.statusText ? this.setState({ add_status: res.statusText }) : null;
return this.handle_getAll();
})
.catch(error => {
this.setState({ add_status: error.message })
});
}
}
handle_delete(e) {
e.preventDefault();
const id = this.state.delete_id;
const delete_url = myUrl + '/' + id.toString();
axios.delete(delete_url)
.then(res => {
console.log(res);
console.log(res.data);
res.statusText ? this.setState({ delete_status: res.statusText }) : null;
return this.handle_getAll();
})
.catch(error => {
this.setState({ delete_status: error.message });
});
}
handle_update(e) {
e.preventDefault();
const id = this.state.update_id;
const update_url = myUrl + '/' + id.toString();
const name = this.state.name_update;
const complete = this.state.iscomplete_update === "true" ? true : false;
if (name !== "") {
axios.put(update_url, { id: id, name: name, isComplete: complete })
.then(res => {
console.log(res);
console.log(res.data);
res.statusText ? this.setState({ update_status: res.statusText }) : null;
return this.handle_getAll();
})
.catch(error => {
this.setState({ update_status: error.message })
});
}
}
render() {
const show_state = {
name_input: this.state.name_input,
name_update: this.state.name_update,
isComplete_input: this.state.iscomplete_input,
isComplete_update: this.state.iscomplete_update,
delete_id: this.state.delete_id,
update_id: this.state.update_id,
get_status: this.state.get_status,
add_status: this.state.add_status,
delete_status: this.state.delete_status,
update_status: this.state.update_status,
}
const show_state_by_line = JSON.stringify(show_state).split(",").
map((item, index) => (
<div key={index}>{item}</div>
));
const complete_options = [
<option key={1}>false</option>,
<option key={2}>true</option>
]
return (
<div >
this.state:
{show_state_by_line}
<br />
<Button size="sm" onClick={() => this.handle_getAll()}> get all</Button>
{this.state.get_status}
{arrayToString_func(this.state.items)}
<Form inline onSubmit={(e) => this.handle_post(e)}>
<FormGroup >
add item:
<Input type="text" bsSize="sm" placeholder="name" required="required"
onChange={(e) => this.setState({ name_input: e.target.value, add_status: "" })} />
<Input type="select" bsSize="sm"
onChange={(e) => this.setState({ iscomplete_input: e.target.value, add_status: "" })}>
{complete_options}</Input>
{this.state.add_status}
</FormGroup>
<Button size="sm" type="submit"> post</Button>
</Form>
<br />
<Form inline onSubmit={(e) => this.handle_delete(e)}>
<FormGroup >
Delete id:
<Input type="number" bsSize="sm" placeholder={-1} required="required"
onChange={(e) => this.setState({ delete_id: parseInt(e.target.value), delete_status: "" })} />
{this.state.delete_status}
</FormGroup>
<Button size="sm" type="submit"> delete</Button>
</Form>
<br />
<Form inline onSubmit={(e) => this.handle_update(e)}>
<FormGroup >
Update id:
<Input type="number" bsSize="sm" placeholder={-1} required="required"
onChange={(e) => this.setState({ update_id: parseInt(e.target.value), update_status: "" })} />
<Input type="text" bsSize="sm" placeholder="name" required="required"
onChange={(e) => this.setState({ name_update: e.target.value, update_status: "" })} />
<Input type="select" bsSize="sm"
onChange={(e) => this.setState({ iscomplete_update: e.target.value, update_status: "" })}>
{complete_options}</Input>
{this.state.update_status}
</FormGroup>
<Button size="sm" type="submit"> update</Button>
</Form>
</div>
);
}
}
const arrayToString_func = (array_input) => (
<ul>{
array_input.map((item, index) => (
<li key={index}>{JSON.stringify(item)}</li>
))
}
</ul>
);
const myUrl = "http://localhost:53664/api/values";
export default App;
reference:
http://chuanshuoge2.blogspot.com/2018/06/react-aspnet.html
Subscribe to:
Posts (Atom)