How to post json object from array in http post request flutter? - arrays

I am working on quiz I have saved the question id and the option id in array now I have to post these data in http post method in json object. I don't know how to convert array into json object
here is my http.post method..
submit(testId,List<String> answer) async {
try {
Response response = await post(
Uri.parse(NetworkConstants.BASE_URL + 'get-participate-to-test/${widget.id}'),
headers: {
"Authorization": "Bearer $token"
},
body:json.encode(
{
'test_id': testId,
'question': answer,
}
));
if (response.statusCode == 200) {
var data = jsonDecode(response.body.toString());
print(data);
showToast(context, data['message']);
// Navigator.of(context).pushAndRemoveUntil(
// MaterialPageRoute(builder: (context) => HomeScreen()),
// (Route<dynamic> route) => false);
} else {
var data = jsonDecode(response.body.toString());
print(data);
showToast(context, data['message']);
}
} catch (e) {
setState(() {
print(e);
});
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text("Exception:"),
content: Text(e.toString()),
actions: [
TextButton(
child: Text("Try Again"),
onPressed: () {
Navigator.of(context).pop();
},
)
],
);
});
}
}
here I am sending Variable (answer) as list [{question_id: 2, option_id: 14}]
how to convert it in json encode object and post in the body of the method?

Here the answer is List of Map<String, int>. You are are already converting it to json by using json.encode in body.
submit(testId,List<Map, String> answer) async {
try {
Response response = await post(
Uri.parse(NetworkConstants.BASE_URL + 'get-participate-to-test/${widget.id}'),
headers: {
"Authorization": "Bearer $token"
},
body:json.encode(
{
'test_id': testId,
'question': answer,
}
));
if (response.statusCode == 200) {
var data = jsonDecode(response.body.toString());
print(data);
showToast(context, data['message']);
// Navigator.of(context).pushAndRemoveUntil(
// MaterialPageRoute(builder: (context) => HomeScreen()),
// (Route<dynamic> route) => false);
} else {
var data = jsonDecode(response.body.toString());
print(data);
showToast(context, data['message']);
}
} catch (e) {
setState(() {
print(e);
});
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text("Exception:"),
content: Text(e.toString()),
actions: [
TextButton(
child: Text("Try Again"),
onPressed: () {
Navigator.of(context).pop();
},
)
],
);
});
}

Related

sending multiple base64 images to cloudinary using node and getting error -4064, code: 'ENAMETOOLONG'

I am getting my base64 urls and they are correct because if I send only one image its uploaded correctly to cloudinary but when sending multiple images Ii get an error 'ENAMETOOLONG' with error number 4064
here is my graphql resolver
createEvent: async (args: any, req: any) => {
if (!req.isAuth) {
throw new Error("Unauthenticated!!!!");
}
let imagesArr: any[] = [];
for (let i = 0; i < args.eventInput.images.length; i++) {
const result = await cloudinary.uploader.upload(
args.eventInput.images[i],
{
public_id: `${args.eventInput.title}${new Date(
args.eventInput.date
)}${i}`,
folder: "Eventers",
allowedFormats: ["jpeg", "png", "jpg"],
}
);
console.log(result.url, result.public_id);
imagesArr.push({ public_id: result.public_id, url: result.secure_url });
}
const event = new Event({
title: args.eventInput.title,
description: args.eventInput.description,
price: +args.eventInput.price,
date: new Date(args.eventInput.date),
category: args.eventInput.category,
brief: args.eventInput.brief,
tickets: +args.eventInput.tickets,
images: [...imagesArr],
author: req.userId,
});
let createdEvent;
try {
const result = await event.save();
createdEvent = transformEvent(result);
const author = await User.findById(req.userId);
if (!author) {
throw new Error("User not found.");
}
author.createdEvents.push(event);
await author.save();
return createdEvent;
} catch (error) {
console.log(error);
throw error;
}
},
here is the response i get when trying to submit multiple base64 urls
message: "Unexpected error value: { error: { errno: -4064, code: \"ENAMETOOLONG\", syscall: \"open\", path: \"C:\\\\Users\\\\user\\\\Desktop\\\\graphQl maximillian yt course\\\\bookingEvents\\\\backend\\\\data:image\\\\jpeg;base64,\\\\9j\\\\4AAQSkZJRgABAQAAAQABAAD\\\\2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSj\\\\2wBDAQcHBwoIChMKChMoGhYaKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCj\\\\wAARCAQIAkUDASIAAhEBAxEB\\\\8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL\\\\8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6\\\\8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL\\\\8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uP…"
and here is how i transform the images to base
const fileOnChangeHandler = async (e: ChangeEvent<HTMLInputElement>) => {
let files = Array.from(e.target.files!);
files.forEach((file: any) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onloadend = async () => {
setImageLinks((prevArr: any) => [...prevArr, reader.result]);
};
});
};
and here is how i send the data to the back end
export const fetchAsyncCreateEvents = createAsyncThunk(
"Events/fetchAsyncCreateEvents",
async (eventInput: Event) => {
const {
title,
category,
description,
brief,
price,
date,
tickets,
images,
} = eventInput;
const { data } = await axios.post<Event>(
API,
{
query: `
mutation{
createEvent(eventInput:{title:"${title}",category:"${category}",description:"""${description}""",brief:"${brief}",price:${price},date:"${date}",tickets:${tickets},images:"${images}"}){
author{
email
}
}
}
`,
},
{
headers: {
"Content-Type": "application/json",
Authorization: "Bearer " + localStorage.getItem("token"),
},
}
);
return data;
}
);
I've tried alot of things like adding .replace(/(\r\n|\n|\r)/gm,"") to the for loop at each image array index but it didnt work
and here is one of the base 64 urls
"data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSj/2wBDAQcHBwoIChMKChMoGhYaKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCj/wAARCAQIAkUDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4"
I deleted more than half of the url so I could submit the question.
i solved the problem it was so simple the problem is i am sending the array of images base64 in a wrong way in graphql mutation
i was sending it with a quotation wrapping it and it turned out you have to use quotations only for strings and for arrays you should json.stringify
export const fetchAsyncCreateEvents = createAsyncThunk(
"Events/fetchAsyncCreateEvents",
async (eventInput: Event) => {
const {
title,
category,
description,
brief,
price,
date,
tickets,
images,
} = eventInput;
const { data } = await axios.post<Event>(
API,
{
query: `
mutation{
createEvent(eventInput:{title:"${title}",category:"${category}",description:"""${description}""",brief:"${brief}",price:${price},date:"${date}",tickets:${tickets},images:${JSON.stringify(images)}}){
author{
email
}
}
}
`,
},
{
headers: {
"Content-Type": "application/json",
Authorization: "Bearer " + localStorage.getItem("token"),
},
}
);
return data;
}
);

How to fix the re- render array for each post from backend to frontend

when I am trying to make a post request then it renders whole a new array and therefore it causes multiple posts and in that array it makes whole posts re-render...
Pls, help me to figure out the problem which I am facing right now...
in-browser console which is a problem
img is blw...
click here...
from backend node js {post route}
const express = require('express');
const router = express.Router();
const multer = require('multer');
const path = require ('path');
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './uploads');
},
filename: function (req, file, cb) {
return cb(null, `${file.fieldname}_${Date.now()}${path.extname(file.originalname)}`);
}
});
const uploadImg = multer({
storage: storage,
fileFilter : (req, file, cb) => {
// reject a file
if (file.mimetype === 'image/jpeg' || file.mimetype === 'image/png') {
cb(null, true);
} else {
console.log('only jpeg and png are accepted!!!')
cb(null, false)
}
},
limits: {
fileSize: 1024 * 1024 * 5
},
}
).single('image');
const {Posts} = require('../models/Posts');
// Get All post
router.get('/posts', (req, res, next) => {
Posts.find({}, (err, data) => {
if (!err) {
res.send(data);
} else {
console.log(err);
}
});
});
router.post('/posts/add', uploadImg, (req, res, next) => {
if (!req.file) return res.send('Please upload a file');
console.log(req.body);
const pos = new Posts({
title: req.body.title,
image: req.file.filename,
HeadingTitle: req.body.HeadingTitle,
datetime: req.body.datetime,
smallTitle: req.body.smallTitle,
MoviesContent: req.body.MoviesContent,
DownloadLinkButtonsHeading: req.body.DownloadLinkButtonsHeading,
Buttons: req.body.Buttons,
allCategories: req.body.allCategories,
});
pos.save((err, data) => {
const image = `http://localhost:5000/${req.file.filename}`
res.status(200).json({
code: 200, message: 'post Added Sucessfully',
addPosts: data,
image: image
})
})
});
// Get Single ID
router.get('/posts/:id', (req, res, next) => {
Posts.findById(req.params.id, (err, data) => {
if (!err) {
res.send(data);
} else {
console.log(err);
}
});
});
// Update post
router.put('/posts/edit/:id', (req, res, next) => {
if (!req.file) return res.send('Please upload a file');
const pos = {
post: req.body,
title: req.body.title,
image: req.file.filename,
HeadingTitle: req.body.HeadingTitle,
datetime: req.body.datetime,
smallTitle: req.body.smallTitle,
MoviesContent: req.body.MoviesContent,
DownloadLinkButtonsHeading: req.body.DownloadLinkButtonsHeading,
Buttons: req.body.Buttons,
allCategories: req.body.allCategories,
};
Posts.findByIdAndUpdate(req.params.id, { $set: pos }, { new: true }, (err, data) => {
if (!err) {
res.status(200).json({
code: 200, message: 'post Updated Successfully',
updatePosts: data
})
} else {
console.log(err);
}
});
});
// Delete post
router.delete('/posts/:id', (req, res, next) => {
Posts.findByIdAndRemove(req.params.id, (err, data) => {
if (!err) {
res.status(200).json({
code: 200, message: 'post Deleted Successfully',
deletePosts: data
});
} else {
console.log(err);
}
});
})
module.exports = router
post schema from backend
const mongoose = require('mongoose');
const Posts = mongoose.model('Posts', {
title: {
type: String
},
image: {
type: String
},
HeadingTitle: {
type: String
},
datetime: {
type: Number
},
smallTitle: {
type: String
},
MoviesContent: {
type: String
},
DownloadLinksButtonsHeading: {
Buttons: {
type: String
}
},
allCategories:{
type:String
}
});
module.exports = {Posts}
frontend code for mapping all post
import React, { useState, useEffect } from 'react'
import './Section.css'
import {
BrowserRouter as Router,
Link
} from "react-router-dom";
// import api from './components/api/post';
function Section() {
const [posts, setPosts] = useState([]);
const Fetchpost = async () => {
const response = await fetch('http://localhost:5000/posts');
setPosts(await response.json());
}
useEffect(() => {
Fetchpost();
}, []);
console.log(posts);
return (
<>
{
posts.map((post) => {
return (
<div key= {post._id}className="samplecontainer">
<div className="r1">
<>
<img src={`http://localhost:5000/${post.image}`} alt="myimg" />
<Link to={post.title}></Link>
<p className="heading">{post.title}</p>
</>
</div>
</div>
)
})
}
</>
)
}
export default Section

404 on webapi custom route

I am really struggling with this
I have an action controller like this:
[HttpPost]
[Route("api/SiteCollections/SetSiteCollectionActive")]
public async Task<IHttpActionResult> SetSiteCollectionActive(string siteCollectionUrl)
{
var siteCollectionsStore = CosmosStoreFactory.CreateForEntity<TenantManagementWebApi.Entities.SiteCollection>();
var allSiteCollections = await siteCollectionsStore.Query().Where(x => x.Title != null).ToListAsync();
foreach (TenantManagementWebApi.Entities.SiteCollection sc in allSiteCollections)
{
sc.Active = false;
await siteCollectionsStore.UpdateAsync(sc);
}
var siteCollection = await siteCollectionsStore.Query().FirstOrDefaultAsync(x => x.Id == siteCollectionUrl);
if (siteCollection == null)
{
return NotFound();
}
siteCollection.Active = true;
var result = await siteCollectionsStore.UpdateAsync(siteCollection);
return Ok(result);
}
and from a reactjs application, I am trying to do the following:
// rowSelection object indicates the need for row selection
const rowSelection = {
onChange: (selectedRowKeys, selectedRows) => {
if(selectedRows[0].Url != undefined){
console.log(selectedRows[0].Url);
const options = {
method: 'post'
};
adalApiFetch(fetch, "/SiteCollections/SetSiteCollectionActive?siteCollectionUrl="+selectedRows[0].Url.toString(), options)
.then(response =>{
if(response.status === 200){
Notification(
'success',
'Site Collection set to active',
''
);
}else{
throw "error";
}
})
.catch(error => {
Notification(
'error',
'Site Collection not activated',
error
);
console.error(error);
});
}
},
getCheckboxProps: record => ({
type: Radio
}),
};
return (
<Table rowSelection={rowSelection} columns={columns} dataSource={this.state.data} />
);
However, I always get this error:
everything seems correct
Route Config
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}

How do I mock a promise in reactjs?

I want to write a test which mocks a promise in reactjs
I just need a mocked implementation of getHeaders() to return a string
export const loadAllProjects = () => {
return (dispatch) => {
getHeaders()
.then(headers => {
...do stuff
})
}
}
to clarify my original function was...
export const loadAllProjects = () => {
return (dispatch) => {
...do stuff
}
}
...and my test was...
it('should create SET_ALL_PROJECTS action when fetching projects', () => {
fetchMock
.getOnce('http://test.projects.api/api/projects',
{
body: [{name: "x"}],
headers: { 'content-type': 'application/json' }
}).spy()
const expectedActions = [
{ type: "SET_ALL_PROJECTS", json: [{name:"x"}] },
]
checkAsyncActionsWereDispatched(expectedActions, actions.loadAllProjects)
});
I want the test to work with the mocked header
const getHeaders = () => {
return new Promise((resolve, reject) => {
resolve("some string");
});
};
a = await getHeaders(); //some string
Use Promise.resolve
return Promise.resolve("your headers here");
You can use jest to mock a promise for testing
Example for the eventual completion:
const mockPostSpy = jest
.spyOn(axios, 'post')
.mockImplementation(() => {
return new Promise((resolve) => {
return resolve({
data: {},
});
});
});
Example for the operation failed:
const mockPostSpy = jest
.spyOn(axios, 'post')
.mockImplementation(() => {
return new Promise((resolve) => {
return reject({});
});
});
Good luck to you ^^

cant .then Promise in react / redux / thunk

Completely new to JS, react, redux and thunk all together.
I am fetching data from an endpoint and I want to site to load / display an error if the fetch was resolved or rejected, but somehow I cant call .then on the fetch I return in my actioncreator.
//projectApi.js
function add(project){
const requestOptions = {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(
project
)
};
return fetch(config.apiUrl + "/projects", requestOptions).then(handleResponse);
}
function handleResponse(response) {
return new Promise((resolve, reject) => {
if (response.ok) {
var contentType = response.headers.get("content-type");
if (contentType && contentType.includes("application/json")) {
response.json().then(json => resolve(json));
} else {
resolve();
}
} else {
response.json().then(json => reject(json));
}
});
}
Then in my ActionCreator I'm doing this:
//projectActions.js
function add(project){
return dispatch => {
dispatch(request());
return projectApi.add(project)
.then( project => {
dispatch(success(project));
},
error => {
dispatch(failure(error));
}
);
};
function request() {
// left out for brevity
}
function success(project) {
// left out for brevity
}
function failure(error) {
// left out for brevity
}
}
However, if I now try to .then my dispatch...
//SomePage.js
handleSubmit(e) {
e.preventDefault();
var project = { name: this.state.projectName };
this.props.add(project).then(...);
}
...
function mapDispatchToProps(dispatch) {
return {
add: (project) => {
dispatch(projectActions.add(project));
}
};
}
I get "TypeError: this.props.add(...) is undefined", however all the actions are properly dispatched. (e.g. request, failure, success) and the store is updated.
Sorry if its a really stupid mistake.

Resources