how can i POST data from ant design form into Django Backed? - django

i trying to post data from ant design React.js into Python Django rest frame work.
so I am using method OnFinish to send data, but its not working.
MY big problem is , i don't know how can i Introduction Data i want to send them data from Form , by using React-redux or something else way , so please Help me .
#react.js Form:
import React, { Component } from "react";
import {
Form,
Input,
Button,
PageHeader,
Select,
DatePicker,
message,
} from "antd";
import "antd/dist/antd.css";
import { connect } from "react-redux";
import axios from "axios";
// defualt setting for django
axios.defaults.xsrfCookieName = "csrftoken";
axios.defaults.xsrfHeaderName = "X-CSRFToken";
// from layout setting
const formItemLayout = {
labelCol: {
xs: {
span: 24,
},
sm: {
span: 8,
},
},
wrapperCol: {
xs: {
span: 24,
},
sm: {
span: 16,
},
},
};
const tailFormItemLayout = {
wrapperCol: {
xs: {
span: 24,
offset: 0,
},
sm: {
span: 16,
offset: 8,
},
},
};
// end fform layout setting
// const onFinish = (values) => {
// console.log(values);
// axios.post("http://127.0.0.1:8000/api/create/", {
// title: values.title,
// manager: values.manager,
// });
// };
// const title = event.target.elements.title.value;
// const manager = event.target.elements.manager.value;
class ExtrashiftForm extends React.Component {
constructor(props) {
super(props);
this.state = {
Extrashifts: [],
};
}
// componentDidMount() {
// this.fetchExtrashift();
// }
handleSubmit = () => {
axios
.post("http://127.0.0.1:8000/api/create", {
data: {
title: this.target.elements.title.value,
manager: this.data.item.manager,
},
})
.then((res) => {
if (res.status == 200) message.success("data successfully updated!");
this.fetchExtrashift();
})
.catch((err) => {
message.error("data profile failed to update ...");
});
};
render() {
return (
<div>
<Form {...formItemLayout} name="update">
<Form.Item label="Title :">
<Input name="title" placeholder="Put a title here" />
</Form.Item>
<Form.Item label="Manager :">
<Input name="manager" placeholder="Enter manager name" />
</Form.Item>
<Form.Item {...tailFormItemLayout}>
<Button
type="primary"
htmlType="submit"
onFinish={this.handleSubmit}
>
create
</Button>
</Form.Item>
</Form>
</div>
);
}
}
export default ExtrashiftForm;
#back end api/urls.py :
from Extrashift.api.views import ExtrashiftViewSet
from rest_framework.routers import DefaultRouter
router = DefaultRouter()
router.register(r'', ExtrashiftViewSet, basename='Extrashift')
urlpatterns = router.urls
#backend : api/views.py:
from rest_framework import viewsets
from Extrashift.models import Extrashift
from .Serializers import ExtrashiftSerializers
class ExtrashiftViewSet(viewsets.ModelViewSet):
serializer_class = ExtrashiftSerializers
queryset = Extrashift.objects.all()
from rest_framework import permissions
from rest_framework.generics import (
ListAPIView,
RetrieveAPIView,
CreateAPIView,
UpdateAPIView,
DestroyAPIView
)
from my back end everything is work but Please help me to i can send only one data from this form.
if is possible please ,change my Code to the Correct code

Nothing spectacular here, you can read the docs
Rather than giving the name as a prop to the Input field.
I've passed it as a prop to Form.Item component
You can check the example here
import React, { Component } from "react";
import {
Form,
Input,
Button,
PageHeader,
Select,
DatePicker,
message,
} from "antd";
import "antd/dist/antd.css";
import axios from "axios";
// defualt setting for django
axios.defaults.xsrfCookieName = "csrftoken";
axios.defaults.xsrfHeaderName = "X-CSRFToken";
// from layout setting
const formItemLayout = {
labelCol: {
xs: {
span: 24,
},
sm: {
span: 8,
},
},
wrapperCol: {
xs: {
span: 24,
},
sm: {
span: 16,
},
},
};
const tailFormItemLayout = {
wrapperCol: {
xs: {
span: 24,
offset: 0,
},
sm: {
span: 16,
offset: 8,
},
},
};
// end fform layout setting
// const onFinish = (values) => {
// console.log(values);
// axios.post("http://127.0.0.1:8000/api/create/", {
// title: values.title,
// manager: values.manager,
// });
// };
// const title = event.target.elements.title.value;
// const manager = event.target.elements.manager.value;
export default class ExtrashiftForm extends React.Component {
constructor(props) {
super(props);
this.state = {
Extrashifts: [],
};
}
// componentDidMount() {
// this.fetchExtrashift();
// }
handleSubmit = (values) => {
console.log(values)
// axios
// .post("http://127.0.0.1:8000/api/create", {
// data: {
// title: this.target.elements.title.value,
// manager: this.data.item.manager,
// },
// })
// .then((res) => {
// if (res.status == 200) message.success("data successfully updated!");
// this.fetchExtrashift();
// })
// .catch((err) => {
// message.error("data profile failed to update ...");
// });
};
render() {
return (
<div>
<Form {...formItemLayout} name="update" onFinish={this.handleSubmit}>
<Form.Item label="Title :" name="title">
<Input placeholder="Put a title here" />
</Form.Item>
<Form.Item label="Manager :" name="manager">
<Input placeholder="Enter manager name" />
</Form.Item>
<Form.Item {...tailFormItemLayout}>
<Button
type="primary"
htmlType="submit"
>
create
</Button>
</Form.Item>
</Form>
</div>
);
}
}

Related

TypeError: null is not an object (evaluating 'RNFusedLocation.getCurrentPosition')

Please, am new to react native. Am trying to get the current location through google places autocomplete for android in expo but an getting the error 'TypeError: null is not an object (evaluating 'RNFusedLocation.getCurrentPosition')'
below is my code
Please, am new to react native. Am trying to get the current location through google places autocomplete for android in expo but an getting the error 'TypeError: null is not an object (evaluating 'RNFusedLocation.getCurrentPosition')'
below is my code
App.js
import { StyleSheet, Text, View, StatusBar, PermissionsAndroid, Platform,} from 'react-native';
import HomeScreen from './src/screens/HomeScreen/HomeScreen';
import DestinationSearch from './src/screens/DestinationSearch/DestinationSearch';
import SearchResults from './src/screens/SearchResults/SearchResults';
import { useEffect, useState } from 'react';
//import * as Location from 'expo-location';
import Geolocation, { getCurrentPosition } from 'react-native-geolocation-service';
navigator.geolocation = require('react-native-geolocation-service');
export default function App() {
const androidPermission = async () => {
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
{
title: "Uber App location Permission",
message:
"Uber App needs access to your location " +
"so you can take awesome rides.",
buttonNeutral: "Ask Me Later",
buttonNegative: "Cancel",
buttonPositive: "OK"
}
);
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
console.log("You can use the location");
} else {
console.log("Location permission denied");
}
} catch (err) {
console.warn(err);
}
};
useEffect(() => {
if (androidPermission) {
Geolocation.getCurrentPosition(
(position) => {
console.log(position);
},
(error) => {
// See error code charts below.
console.log(error.code, error.message);
},
{ enableHighAccuracy: true, timeout: 15000, maximumAge: 10000 }
);
}
}, [])
useEffect(() => {
if(Platform.OS == 'android') {
androidPermission()
} else{
//IOS
Geolocation.requestAuthorization();
}
}, [])
return (
<View>
{/* <HomeScreen /> */}
<DestinationSearch />
{/* <SearchResults /> */}
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
marginTop:StatusBar.currentHeight
},
});
`
DestinationSearch.jsx
import { View, Text, StyleSheet, SafeAreaView, StatusBar } from 'react-native'
import React, {useEffect, useState,} from 'react'
import { GooglePlacesAutocomplete } from 'react-native-google-places-autocomplete';
import {GOOGLE_MAPS_APIKEY} from '#env'
import PlaceRow from './PlaceRows';
const DestinationSearch = () => {
const [originPlace,setOriginPlace] = useState(null)
const [destinationPlace, setDestinationPlace] = useState(null)
useEffect(() => {
console.log('useEffect is called')
if (originPlace && destinationPlace) {
console.warn('Redirect to results')
}
}, [originPlace, destinationPlace])
return (
<SafeAreaView>
<View style={styles.container}>
<GooglePlacesAutocomplete
nearbyPlacesApi = 'GooglePlacesSearch'
placeholder = 'From...'
listViewDisplayed = 'auto'
debounce = {400}
currentLocation = {true}
currentLocationLabel='Current location'
minLenght = {2}
enabledPoweredByContainer = {true}
fetchDetails = {true}
autoFoccus = {true}
renderRow={(data)=> <PlaceRow data={data}/>}
query ={{
key: GOOGLE_MAPS_APIKEY ,
language :'en'
}}
styles={{
container: styles.autocompleteContainer,
textInput: styles.textInput,
listView: styles.listView,
seperator: styles.separator
}}
onPress = {(data, details = null)=> {
setOriginPlace({data, details})
console.log(currentLocation)
}}
/>
<GooglePlacesAutocomplete
nearbyPlacesApi = 'GooglePlacesSearch'
placeholder = 'To...'
listViewDisplayed = 'auto'
debounce = {400}
minLenght = {2}
enabledPoweredByContainer = {true}
fetchDetails = {true}
autoFoccus = {true}
query ={{
key: GOOGLE_MAPS_APIKEY ,
language :'en'
}}
renderRow={(data)=> <PlaceRow data={data}/>}
styles={{
container: {
...styles.autocompleteContainer,
top: 70
},
textInput: styles.textInput,
seperator: styles.separator
}}
onPress = {(data, details = null)=> {
setDestinationPlace({data, details})
}}
/>

How can I submit form without button in unit test?

The fireEvent.submit(form) call doesn't seem to be submitting the form. How can I submit the form?
BasicInfo/index.test.tsx
import { fireEvent, render, screen, waitFor } from '#testing-library/react';
import userEvent from '#testing-library/user-event';
import BasicInfo from '.';
describe('BasicInfo', () => {
it('can submit form', async () => {
const handleSubmit = jest.fn();
render(<BasicInfo onSubmit={handleSubmit} />);
const user = userEvent.setup();
await user.type(screen.getByLabelText('Event title'), 'Event title 1');
await user.type(screen.getByLabelText('Featured game'), 'Scrabble');
await user.type(screen.getByLabelText('Venue location'), '21 2nd St.');
await user.type(screen.getByLabelText('Event starts'), '2017-06-01T08:30');
await user.type(screen.getByLabelText('Event ends'), '2017-06-01T08:30');
const form = screen.getByTestId<HTMLFormElement>('basic-info');
fireEvent.submit(form);
await waitFor(() => {
expect(handleSubmit).toHaveBeenCalledWith({
title: 'Event title 1',
game: { name: 'Scrabble' },
address: '21 2nd St.',
starts_at: '2017-06-01T08:30',
ends_at: '2017-06-01T08:30',
});
});
});
});
BasicInfo/index.tsx
import { Form, Formik, FormikErrors, FormikHelpers, FormikProps } from 'formik';
import Image from 'next/image';
import Link from 'next/link';
import { useLocation } from '../../context/location';
import { Event } from '../../hooks/useEvents';
import useGames, { Game } from '../../hooks/useGames';
import useMapbox, { Feature, Coords } from '../../hooks/useMapbox';
import useThrottle from '../../hooks/useThrottle';
import { parseAddress } from '../../lib/helpers';
import AddressItem from '../AddressItem';
import AutoComplete from '../AutoComplete';
import Button from '../Button';
import FormSection from '../FormSection';
import InputGroup from '../InputGroup';
import GameItem from '../GameItem';
export interface BasicInfoValues {
title: string;
game: Game;
address: string;
starts_at: string;
ends_at: string;
coords: string;
}
interface Props {
event?: Event;
initialValues?: BasicInfoValues;
onSubmit: (values: BasicInfoValues) => Promise<void>;
}
function BasicInfo({ event, initialValues: initialVals, onSubmit }: Props) {
const { coords } = useLocation();
const { data: places, forward, getStaticMapUrl } = useMapbox();
const { data: games, search, leanGame } = useGames();
const throttle = useThrottle();
const initialValues: BasicInfoValues = initialVals || {
title: '',
game: { name: '' },
address: '',
starts_at: '',
ends_at: '',
coords: '',
};
const validate = (values: BasicInfoValues) => {
const errors: FormikErrors<BasicInfoValues> = {};
if (values.title.length < 3) {
errors.title = 'Must be at least 3 characters';
}
if (values.title.length > 50) {
errors.title = 'Must be less than 50 characters';
}
if (!values.game.name) {
errors.game = 'Must select a game' as FormikErrors<Game>;
}
if (!values.coords) {
errors.coords = 'Must select a location';
}
if (!values.starts_at) {
errors.starts_at = 'Required';
}
if (!values.ends_at) {
errors.ends_at = 'Required';
}
return errors;
};
const handleSubmit = async function (
values: BasicInfoValues,
formikHelpers: FormikHelpers<BasicInfoValues>
) {
try {
await onSubmit(values);
formikHelpers.setSubmitting(false);
} catch (error) {
console.error(error);
}
};
const renderLocation = function ({
setFieldValue,
values,
handleChange,
errors,
touched,
handleBlur,
}: FormikProps<BasicInfoValues>) {
const handleEditLocationClick = function () {
setFieldValue('address', '');
setFieldValue('coords', '');
};
const { coords: coordinates, address } = values;
if (coordinates && address) {
const staticMapUrl = getStaticMapUrl({
coords: JSON.parse(coordinates),
width: 600,
height: 165,
});
const { street, city } = parseAddress(address);
return (
<div className="basic-info__location">
<div className="basic-info__location__image-container">
<Image
src={staticMapUrl}
alt="static map"
layout="fill"
objectFit="fill"
/>
</div>
<div className="basic-info__location__address-container">
<div className="basic-info__location__address-container__address">
<span className="basic-info__location__street">{street}</span>
<span className="basic-info__location__city">{city}</span>
</div>
<Button
text="Edit location"
color="secondary"
size="small"
onClick={handleEditLocationClick}
/>
</div>
</div>
);
} else {
return (
<AutoComplete<Feature>
name="address"
value={values.address}
onChange={(e) => {
if (!handleChange) return;
handleChange(e);
throttle.wait(() => {
if (!e.target.value) return;
if (!coords) return;
forward({
coords,
q: e.target.value,
});
}, 500);
}}
label="Venue location"
placeholder="Search for a venue or address"
items={places}
Input={InputGroup}
itemRenderer={(item) => <AddressItem placeName={item.place_name} />}
onItemClick={(item) => {
if (!setFieldValue) return;
setFieldValue('address', item.place_name);
setFieldValue('coords', JSON.stringify(item.center));
}}
onBlur={handleBlur}
error={errors.coords && touched.address ? errors.coords : undefined}
/>
);
}
};
return (
<Formik
initialValues={initialValues}
onSubmit={handleSubmit}
validate={validate}
>
{(formikProps) => {
const {
values,
handleChange,
setFieldValue,
errors,
touched,
handleBlur,
} = formikProps;
return (
<Form id="basic-info" className="basic-info" data-testid="basic-info">
<FormSection
title="Basic Info"
description="Name your event and tell gamers what game will be played. Add
details that highlight what makes it unique."
icon="segment"
>
<InputGroup
name="title"
value={values.title}
onChange={handleChange}
onBlur={handleBlur}
label="Event title"
placeholder="Be clear and descriptive"
error={errors.title && touched.title ? errors.title : undefined}
/>
<AutoComplete<Game>
name="game.name"
value={values.game.name}
onBlur={handleBlur}
onChange={(e) => {
handleChange(e);
throttle.wait(() => {
if (!e.target.value) return;
search({ name: e.target.value, limit: 5 });
}, 500);
}}
label="Featured game"
placeholder="Search games"
Input={InputGroup}
items={games}
itemRenderer={(item) => <GameItem game={item} />}
onItemClick={(item) => {
const game = leanGame(item);
setFieldValue('game', game);
}}
error={
errors.game && touched.game
? (errors.game as string)
: undefined
}
/>
<span>
Need game ideas?{' '}
<Link href="/" passHref>
<a className="link">Browse games by category</a>
</Link>
</span>
</FormSection>
<FormSection
title="Location"
description="Help gamers in the area discover your event and let attendees know where to show up."
icon="map"
>
{renderLocation(formikProps)}
</FormSection>
<FormSection
title="Date and time"
description="Tell gamers when your event starts and ends so they can make plans to attend."
icon="date_range"
>
<InputGroup
name="starts_at"
value={values.starts_at}
onChange={handleChange}
onBlur={handleBlur}
label="Event starts"
placeholder="Search for a venue or address"
type="datetime-local"
// icon="calendar_today"
error={
errors.starts_at && touched.starts_at
? errors.starts_at
: undefined
}
/>
<InputGroup
name="ends_at"
value={values.ends_at}
onChange={handleChange}
onBlur={handleBlur}
label="Event ends"
placeholder="Search for a venue or address"
type="datetime-local"
// icon="calendar_today"
error={
errors.ends_at && touched.ends_at ? errors.ends_at : undefined
}
/>
</FormSection>
</Form>
);
}}
</Formik>
);
}
export default BasicInfo;
My form validation was preventing me from submitting

TypeError: Cannot read property 'getters' of undefined on Vue Jest Test

This is my test file
import { shallowMount, createLocalVue } from '#vue/test-utils';
import Home from '#/views/Home.vue';
import Vuex from 'vuex';
import Vuetify from 'vuetify';
import movies from '#/store/modules/movies';
const localVue = createLocalVue();
localVue.use(Vuex);
describe('Home.vue', () => {
let vuetify;
let store;
let state;
let actions;
beforeEach(() => {
state = {
movieList: [],
movieDetails: {},
};
actions = {
getMovieList: jest.fn(),
getMovieDetails: jest.fn(),
};
store = new Vuex.Store({
modules: {
movies: {
namespaced: true,
state,
actions,
},
},
});
vuetify = new Vuetify();
});
const wrapper = shallowMount(Home, {
store,
vuetify,
localVue,
});
it('should call submitForm() function when button is clicked', () => {
wrapper.find('button').trigger('click');
expect(wrapper.vm.submitForm).toHaveBeenCalled();
});
});
This is my view file
<script>
import Tooltip from '#/components/Tooltip.vue';
import { moviesComputed, moviesMethods } from '#/store/helpers/movies';
export default {
components: {
Tooltip,
},
methods: {
...moviesMethods,
submitForm() {
const validate = this.$refs.form.validate();
if (!validate) return;
this.currentPage = 1;
this.getMoviesList({ s: this.searchQuery });
},
async goToDetails(moveId) {
this.$router.push({ name: 'MovieDetails', params: { id: moveId } });
},
onScroll() {
const isOnBottom = document.documentElement.scrollTop + window.innerHeight
=== document.documentElement.offsetHeight;
if (isOnBottom) {
this.currentPage += 1;
this.nextMoviePage({ s: this.searchQuery, page: this.currentPage });
}
},
},
computed: {
...moviesComputed,
pagedMovieList() {
const listNumber = this.maxList * this.currentPage;
const list = this.movieList.filter((movie, index) => index < listNumber);
return list;
},
},
data() {
return {
searchQuery: '',
queryRules: [(v) => !!v || 'Antes de pesquisar, forneça um nome'],
mouseOverIndex: '',
maxList: 6,
currentPage: 1,
};
},
async mounted() {
document.addEventListener('scroll', this.onScroll);
},
beforeDestroy() {
document.removeEventListener('scroll', this.onScroll);
},
};
</script>
<template>
<div id="home">
<v-row class="justify-center align-center">
<v-col class="home-form" :class="{ 'to-top': movieList.length }" sm="12" md="6" xl="4">
<v-form ref="form" color="secondary" #submit="submitForm">
<v-text-field
label="Digite sua busca"
append-icon="mdi-magnify"
:rules="queryRules"
v-model="searchQuery"
required
/>
</v-form>
<v-btn color="secondary" class="mt-1" #click="submitForm">Enviar</v-btn>
</v-col>
</v-row>
<v-row class="mt-5">
<v-col
cols="12"
sm="6"
md="4"
v-for="(movie, index) in pagedMovieList"
:key="`${movie.Title}-${index}`"
style="position: relative"
>
<v-card elevation="10" #mouseover="mouseOverIndex = index" #mouseout="mouseOverIndex = ''">
<p class="mt-1 text-center" v-if="movie.Poster === 'N/A'">{{ movie.Title }}</p>
<v-img v-if="movie.Poster !== 'N/A'" :src="movie.Poster" />
<v-img v-else src="#/assets/not-found.png" />
<Tooltip #clicked="goToDetails" :active="index === mouseOverIndex" :movie="movie" />
</v-card>
</v-col>
</v-row>
</div>
</template>
This is my store module file
import { GetList, GetDetails } from '#/services/movies';
export const state = {
movieList: [],
movieDetails: {},
};
export const mutations = {
SET_LIST(state, newList) {
state.movieList = newList;
},
SET_MOVIE_DETAILS(state, newValue) {
state.movieDetails = newValue;
},
ADD_TO_LIST(state, list) {
state.movieList.push(...list);
},
};
export const actions = {
async getMoviesList({ commit }, query) {
const resp = await GetList(query);
if (resp.status === 200) commit('SET_LIST', resp.data.Search);
},
async getMovieDetails({ commit }, movieId) {
const resp = await GetDetails({ i: movieId });
if (!resp.status === 200) return;
commit('SET_MOVIE_DETAILS', resp.data);
},
async nextMoviePage({ commit }, query) {
const resp = await GetList(query);
if (resp.status === 200 && resp.data.Search) commit('ADD_TO_LIST', resp.data.Search);
},
};
const movies = {
namespaced: true,
mutations,
state,
actions,
};
export default movies;
This is my base.js module file
export const state = {
isLoading: false,
};
export const mutations = {
SET_LOADING(state, newValue) {
state.isLoading = newValue;
},
};
export const actions = {
setLoading({ commit }, value) {
commit('SET_LOADING', value);
},
};
const base = {
namespaced: true,
mutations,
state,
actions,
};
export default base;
And this is my store.js
import Vue from 'vue';
import Vuex from 'vuex';
// Modules
import Base from './modules/base';
import Movies from './modules/movies';
Vue.use(Vuex);
export default new Vuex.Store({
modules: {
base: Base,
movies: Movies,
},
strict: process.env.NODE_ENV !== 'production',
});
This is the error
TypeError: Cannot read property 'getters' of undefined
8 | Vue.use(Vuex);
9 |
> 10 | export default new Vuex.Store({
| ^
11 | modules: {
12 | base: Base,
13 | movies: Movies,
I have no idea why I'm getting an error on new Vuex.Store on tests. This application runs normally, without errors on Vuex. I cant even post what I already did to solve this because I'm completely lost

DRF+VueJS pagination wrong number of pages

I am trying to use DRF pagination backend and VueJs Frontend. I am trying to create pagination links but until now i only get first number. I have added PageNumberPagination to my settings.py. After articles viewset:
class ArticleViewSet(viewsets.ModelViewSet):
queryset = Article.objects.all()
lookup_field = "slug"
serializer_class = ArticleSerializer
permission_classes = [IsAuthenticated, IsAuthorOrReadOnly]
pagination_class = PageNumberPagination
I have used Bootstrap-Vue Pagination
<div class="col" id="article-list" :articles="articles" v-for="article in articles" :key="article.pk"
:per-page="perPage"
:current-page="currentPage">...</div>
<b-pagination
v-model="currentPage"
:total-rows="rows"
:per-page="perPage"
aria-controls="articles-list"
></b-pagination>
and VueJS script:
export default {
name: "ArticleList",
components: {
HelloWorld,
} ,
data() {
return {
articles: [],
next: null,
loadingArticles: false,
perPage: 2,
currentPage: 1,
size:2,
}
},
methods: {
getArticles() {
this.loadingArticles = true;
let url = "http://localhost:8000/api/articles";
axios.get(url)
.then(response => {
this.articles = response.data.results;
});
},
},
computed: {
rows() {
console.log(this.articles.length);
return this.articles.length;
}
},
created() {
this.getArticles();
},
};
If i check the api address in the browser, I can see the next and previous data.
{
"count": 4,
"next": "http://localhost:8000/api/articles/?page=2",
"previous": null,
"results": [...]
}
How do I change the data of total-rows to make pagination work? Thanks
Simply I added my next to fetching articles, I answer my question as to request, I now use vuex but VueJs is also similar:
fetchArticles (context) {
context.commit("fetchStart");
let endpoint = "articles/"
if (context.state.next) {
endpoint = context.state.next;
}
return ApiService.get(endpoint)
.then(data=>{
console.log(data);
context.commit("setArticles", data.data.results)
if (data.data.next) {
context.commit("setNext", data.data.next);
} else {
context.commit("setNext", null)
}
})
.catch((response) => {
console.log(response);
context.commit("setError", response.data.errors)
})
},
from my vuetemplate I call it for eg:
<script>
import { mapGetters, mapActions} from "vuex";
export default {
name: "Articles",
computed: {
},
methods: {
...mapActions(['articles/fetchArticles']),
getArticles() {
return this.$store.dispatch('articles/fetchArticles');
},
},
created() {
this.$store.dispatch('articles/fetchArticles').
then(() => {
this.isLoading = false;
})
}
};
</script>
and my button
<li class="page-item disabled">
<button
v-show="next"
#click="getArticles"
class="btn btn-sm btn-primary"
>Devamı...</button>
</li>

Ionic2 Upgrade from beta to rc3: App.html”: Error: ENOENT: no such file or directory

I am in the process of upgrading from Ionic 2 beta to Ionic 2 rc3.
I have my app.component.ts file, that worked fine, when it was just displaying a root page. But as soon as I have tried to add menu items from my old working Ionic 2 beta version, I get the error below.
If anyone can advise how I can resolve this, I would appreciate the help.
Compile Error in CLI
[13:14:56] template error, "E:\Development\IDE\ionic-apps\WhatsAppClone\src\app\build\app.html": Error: ENOENT: no such
file or directory, open 'E:\Development\IDE\ionic-apps\WhatsAppClone\src\app\build\app.html'
Runtime Error in browser console
Unhandled Promise rejection: Failed to load build/app.html ; Zone: meteor-rxjs-zone ; Task: Promise.then ; Value: Failed to load build/app.html undefined polyfills.js:3:7730
Error: Uncaught (in promise): Failed to load build/app.html
Stack trace:
s#http://localhost:8100/build/polyfills.js:3:8568
s#http://localhost:8100/build/polyfills.js:3:8391
h/<#http://localhost:8100/build/polyfills.js:3:8902
sg</d</t.prototype.invokeTask#http://localhost:8100/build/polyfills.js:3:14040
sg</v</e.prototype.runTask#http://localhost:8100/build/polyfills.js:3:11392
i#http://localhost:8100/build/polyfills.js:3:8021
t/this.invoke#http://localhost:8100/build/polyfills.js:3:15204
app.component.ts
import { Component, ViewChild } from '#angular/core';
import { Storage } from "#ionic/storage";
import { Platform, Events, AlertController, Nav } from 'ionic-angular';
import { StatusBar, Push, Splashscreen } from 'ionic-native';
import { SearchJobsPage } from "../pages/searchjobs/searchjobs";
import { LoginPage } from '../pages/login/login';
import { LogoutPage } from '../pages/logout/logout';
import { PersonModel } from '../pages/model/personModel';
import { ChatsPage } from '../pages/chats/chats';
import { PersonPage } from '../pages/person/person';
import { SearchFavouriteJobsPage } from '../pages/searchfavouritejobs/searchfavouritejobs';
import { SearchPostingsPage } from '../pages/searchpostings/searchpostings';
import { SearchFavouritePostingsPage } from '../pages/searchfavouritepostings/searchfavouritepostings';
import { UtilityService } from '../pages/utils/utilityService';
import { NotificationService } from '../pages/service/notificationService';
import { JobService } from '../pages/service/jobService';
import { JobModel } from '../pages/model/jobModel';
import { MapLocationsPage } from '../pages/maplocations/maplocations';
import { MapRangePage } from '../pages/maprange/maprange';
//import { METEOR_PROVIDERS } from 'angular2-meteor';
// import * as Check from 'meteor/check';
// import * as EJSON from 'meteor/ejson';
//declare let Meteor;
#Component({
templateUrl: 'build/app.html'
})
export class MyApp {
#ViewChild(Nav) nav: Nav;
rootPage: any;
public storage: Storage = null;
public pages: Array<{ title: string, component: any }>;
public pages_person: Array<{ title: string, component: any }>;
public pages_person_admin: Array<{ title: string, component: any }>;
public menuTitle: string = 'Menu';
public personModel: PersonModel = null;
public utilityService: UtilityService = null;
public notificationService: NotificationService = null;
public personModelLoggedIn: PersonModel;
public jobService: JobService = null;
public events: Events = null;
public ios: boolean = false;
constructor(private platform: Platform, utilityService: UtilityService, notificationService: NotificationService, jobService: JobService, events: Events, private alertCtrl: AlertController, storage: Storage) {
this.storage = storage;
this.utilityService = utilityService;
this.jobService = jobService;
this.notificationService = notificationService;
this.events = events;
this.initializeApp();
if (this.platform.is('ios')) {
this.ios = true;
}
// this.rootPage = Meteor.user() ? TabsPage : LoginComponent;
this.rootPage = SearchJobsPage;
platform.ready().then(() => {
// Okay, so the platform is ready and our plugins are available.
// Here you can do any higher level native things you might need.
this.initializeApp();
StatusBar.styleDefault();
Splashscreen.hide();
});
// used for an example of ngFor and navigation
this.pages = [
{ title: 'Market', component: SearchJobsPage },
{ title: 'Postings', component: SearchPostingsPage },
{ title: 'Login', component: LoginPage }
];
this.pages_person = [
{ title: 'Market', component: SearchJobsPage },
{ title: 'Market Favourites', component: SearchFavouriteJobsPage },
{ title: 'Postings', component: SearchPostingsPage },
{ title: 'Favourite Postings', component: SearchFavouritePostingsPage },
{ title: 'Messages', component: ChatsPage },
{ title: 'Profile', component: PersonPage },
{ title: 'Logout', component: LogoutPage }
];
this.pages_person_admin = [
{ title: 'Market', component: SearchJobsPage },
{ title: 'Market Favourites', component: SearchFavouriteJobsPage },
{ title: 'Postings', component: SearchPostingsPage },
{ title: 'Favourite Postings', component: SearchFavouritePostingsPage },
{ title: 'Messages', component: ChatsPage },
{ title: 'Profile', component: PersonPage },
{ title: 'Logout', component: LogoutPage },
{ title: 'Map Locations', component: MapLocationsPage },
{ title: 'Map Range', component: MapRangePage }
];
}
initializeApp() {
StatusBar.styleDefault();
this.checkLogin();
this.utilityService.startUpChecks();
if (window['cordova']) {
this.utilityService.setLocalStrorage('this.chats.observe', 'false');
this.utilityService.setLocalStrorage('this.messages.observe', 'false');
this.utilityService.setLocalStrorage('this.messages.subscribe', 'false');
this.utilityService.setLocalStrorage('push:notifications.subscribe', 'false');
}
this.subscribeEvents();
}
// openPage(page) {
// // Reset the content nav to have just this page
// // we wouldn't want the back button to show in this scenario
// this.nav.setRoot(page.component);
// }
public subscribeEvents(): void {
this.events.subscribe('push:notifications', (data) => {
this.checkLogin();
});
}
public pushNotifications(): void {
let observedPromise: Promise<string> = this.utilityService.getLocalStrorage('push:notifications.subscribe');
observedPromise.then((observed: string) => {
if (!observed || observed != 'true') {
this.utilityService.setLocalStrorage('push:notifications.subscribe', 'true');
try {
if (window['cordova']) {
if (this.personModelLoggedIn) {
let promiseJobsForPerson: Promise<JobModel[]> = this.jobService.getJobsByPerson(this.personModelLoggedIn.id);
promiseJobsForPerson.then((data) => {
let jobModelsForPerson: JobModel[] = data;
let topics: string[] = [];
topics.push('P' + this.personModelLoggedIn.id);
for (let i = 0; i < jobModelsForPerson.length; i++) {
let jobModel: JobModel = jobModelsForPerson[i];
topics.push('J' + jobModel.id);
}
//topics.push('J65'); // deleteme
//topics.push('P9'); // deleteme
let push = Push.init({
android: {
senderID: "893141127008",
topics: topics
},
ios: {
alert: "true",
badge: false,
sound: "true",
topics: topics
},
windows: {}
});
push.on('registration', (data1) => {
this.events.subscribe('messages:notify', (data) => {
let promise: Promise<string> = this.notificationService.push('null', data[0].topic, data[0].message, data[0].title);
promise.then((data2) => {
// console.log('app.ts messages2:notify', data2);
});
});
});
push.on('notification', (data) => {
this.events.publish('messages:update');
if (this.nav.getActive().name != 'ChatsPage' && this.nav.getActive().name != 'MessagesPage') {
//if user using app and push notification comes
if (data.additionalData.foreground) {
//if application open, show popup
let confirmAlert = this.alertCtrl.create({
title: data.title,
message: data.message,
buttons: [{
text: 'Ignore',
role: 'cancel'
}, {
text: 'View',
handler: () => {
this.rootPage = ChatsPage;
}
}]
});
confirmAlert.present(confirmAlert);
} else {
this.rootPage = ChatsPage;
}
}
});
push.on('error', (e) => {
alert('Error: ' + e.message);
console.log(e);
});
});
}
}
} catch (e) {
alert('Push Notification: ' + e.message());
console.log('Push Notification: ' + e.message());
}
}
});
}
public checkLogin(): void {
let promise: Promise<string> = this.utilityService.getLoggedInPerson();
promise.then((data) => {
this.personModelLoggedIn = JSON.parse(data);
if (this.personModelLoggedIn) {
this.utilityService.setUpMenuItems();
this.pushNotifications();
}
});
}
}
app.html
<ion-menu [content]="content" id="unauthenticated">
<ion-toolbar>
<ion-title>Menu</ion-title>
</ion-toolbar>
<ion-content>
<ion-list>
<button menuClose ion-item *ngFor="let p of pages" (click)="openPage(p)">
{{p.title}}
</button>
</ion-list>
</ion-content>
</ion-menu>
<ion-menu [content]="content" id="authenticated-person">
<ion-toolbar [class]="ios ? 'menu-toolbar' : ''">
<ion-title [class]="ios ? 'menu-title' : ''">
<div class="item-avatar-img" id="menu-item-avatar-img-person"></div>
<div class="item-avatar-name" id="menu-item-avatar-name-person"></div>
</ion-title>
</ion-toolbar>
<ion-content>
<ion-list>
<button menuClose ion-item *ngFor="let p of pages_person" (click)="openPage(p)">
{{p.title}}
</button>
</ion-list>
</ion-content>
</ion-menu>
<ion-menu [content]="content" id="authenticated-person-admin">
<ion-toolbar [class]="ios ? 'menu-toolbar' : ''">
<ion-title [class]="ios ? 'menu-title' : ''">
<div class="item-avatar-img" id="menu-item-avatar-img-person-admin"></div>
<div class="item-avatar-name" id="menu-item-avatar-name-person-admin"></div>
</ion-title>
</ion-toolbar>
<ion-content>
<ion-list>
<button menuClose ion-item *ngFor="let p of pages_person_admin" (click)="openPage(p)">
{{p.title}}
</button>
</ion-list>
</ion-content>
</ion-menu>
<!-- Disable swipe-to-go-back because it's poor UX to combine STGB with side menus -->
<ion-nav [root]="rootPage" #content swipeBackEnabled="false"></ion-nav>
Directory
You have set your templateUrl as build/app.html.
You shouldnt check it in build folder.
Try templateUrl: 'app.html' in app.component.ts