angular http post send complex objects - json

My Service
public submitBooking(createBooking: CreateBooking) {
const body = this.getSaveBookingRequestBody(createBooking);
//const json = JSON.Stringify(body) //It throws 415 error
return this.httpClient.post(this.baseUrl + 'Save', body )
.subscribe();
}
private getSaveBookingRequestBody(createBooking: CreateBooking): any {
const body = {
'Booking': {
'Header': this.getBookingHeader(createBooking), //It works fine.
'Items': [this.getBookingItems(createBooking)],
},
'TestOnly': !environment.production,
};
this.Logger.log(body);
return body;
}
private getBookingItems(createBooking: CreateBooking): any {
const bookingItem = {
'CountryOfOrigin': createBooking.booking.countryoforigin,
'VehicleValue': createBooking.booking.valueofvechicle,
'SerialNumber': createBooking.booking.bookingNumber,
'Description': createBooking.booking.description,
'Mobility': createBooking.booking.mobility,
'Currency': createBooking.booking.currency,
'Weight': createBooking.booking.weight,
'Year': createBooking.booking.year,
'Cbm': createBooking.booking.cbm,
//This is an array it doesn't work.
'SubUnits':[
createBooking.booking.relatedVehicles.forEach(element => {
const units = {
'RelationType': element.relation,
'Weight': element.weight,
'Year': element.year,
};
})],
};
return bookingItem;
When i create POST body the SubUnits always empty in WEB API.
How to loop through array and create an object for sending as body.
My angular model and WEB-API object are different
I have also tried the JSON.Stringify(unitsArray) and returning it to SubUnits
const unitsArray = [];
createBooking.booking.relatedVehicles.forEach(element => {
const units = {
'RelationType': element.relation,
'SerialNumber': element.chassisno,
'Weight': element.weight,
'Year': element.year,
};
unitsArray.push(units);
});
SubUnits : JSON.stringify(unitsArray); // It also doesn't work with API.
Version :
Angular 5
Typescript 2.4.2

const bookingItem = {
...
'SubUnits': [
createBooking.booking.relatedVehicles.forEach(element => {
const units = {
'RelationType': element.relation,
'Weight': element.weight,
'Year': element.year,
};
})
]
...
};
This loop doesnt fill the array in bookingItem.SubUnits. Array.forEach does not return a value. Besides that, the variable units is never used. What you can do instead is create a new array using Array.map.
'SubUnits': [
createBooking.booking.relatedVehicles.map(element => ({
'RelationType': element.relation,
'Weight': element.weight,
'Year': element.year
}))
]
This makes an array with 1 array element from createBooking.booking.relatedVechiles. I am not sure if that's what you are going for, but it is in your OP.

Have you tried to not use JSON.stringify? Just use:
SubUnits :unitsArray;

Related

Merge mixin in vue

I'm working in vue/quasar application.
I've my mixin like this in my view.cshtml
var mixin1 = {
data: function () {
return { data1:0,data2:'' }
}
,
beforeCreate: async function () {
...}
},
methods: {
addformulaire(url) {
},
Kilometrique() { }
}
}
And I want merge with my content in js file (it's to centralize same action an severals cshtml)
const nomeMixins = {
data: function () {
return { loadingcdt: false, lstclt: [], filterclient: [], loadingdoc: false, lstdoc: [], filterdoc: [] }
},
computed: {
libmntpiece(v) { return "toto"; }
},
methods: {
findinfcomplemtX3(cdecltx3, cdedocx3) {
},
preremplissagex3: async function (cdecltx3, cdedocx3) {
}
}
}
};
I want merge this 2 miwin in one. But when I try assign or var mixin = { ...mixin1, ...nomeMixins };
I've only mixin1 nothing about methods,data from my js file nomeMixins but merging failed cause I've same key in my json object. I'm trying to make a foreach but failed too
Someone try to merge to mixin / json object with same key in the case you've no double child property ?
You cant merge mixins in that way. the spread syntax will overwrite keys e.g data, computed, methods etc and final result will not be suitable for your purpose.
refer documentation for adding mixins in your component. Also note that You can easily add multiple mixins in any component, so I don't think combination of two mixins will be any useful.
UPDATE
reply to YannickIngenierie answer and pointing out mistakes in this article
Global Mixins are not declared like this
// not global mixin; on contrary MyMixin is local
// and only available in one component.
new Vue({
el: '#demo',
mixins: [MyMixin]
});
Local Mixins are not declared like this
// NOT local mixin; on contrary its global Mixin
// and available to all components
const DataLoader = Vue.mixin({....}}
Vue.component("article-card", {
mixins: [DataLoader], // no need of this
template: "#article-card-template",
created() {
this.load("https://jsonplaceholder.typicode.com/posts/1")
}
});
Point is refer documentation first before reading any article written by some random guy, including me. Do slight comparison what he is saying whats in documentation.
After working and searching... I find this one And understand that I can add directly mixin in my compoment (don't laught I'm begging with vue few months ago)
my custommiwin.js
const DataLoader = Vue.mixin({
data: function () {
return { loadingcdt: false, lstclt: [], filterclient: [], loadingdoc: false, lstdoc: [], filterdoc: [] }
},
methods: {
filterClt: async function (val, update, abort) {
if (val.length < 3) { abort(); return; }
else {//recherche
this.loadingcdt = true;
let res = await axios...
this.loadingcdt = false;
}
update(() => {
const needle = val.toLowerCase();
this.filterclient = this.lstclt.filter(v => v.libelle.toLowerCase().indexOf(needle) > -1 || v.id.toLowerCase().indexOf(needle) > -1);
})
},
filterDocument: async function (val, update, abort, cdecltx3) {
if (!cdecltx3 || val.length < 3) { abort(); return; }
else {//recherche
this.loadingdoc = true;
let res = await axios({ ...) }
this.loadingdoc = false;
}
update(() => {
const needle = val.toLowerCase();
this.filterdoc = this.lstdoc.filter(v => v.id.toLowerCase().indexOf(needle) > -1);
})
},
}
});
and in my compoment.js I add this
mixins: [DataLoader],
I include all my js file in my cshtml file

Data binding not working on React with object properties

//I tried to render data from the nested object, but retrieve the error message
useEffect(() => {
axios
.get('https://bodyshop.r2.software/wp-json/wp/v2/pages/2')
.then(response => {
const posts = response.data;
const tempObj = {};
for(let key in posts["post-meta-fields"]) {
const modifiedKey = key.replace('_','');
tempObj[modifiedKey] = posts["post-meta-fields"][key]
}
posts["post-meta-fields"] = tempObj;
setList(posts)
console.log(posts);
})
}, [])
// nested object
// posts = {
// ...
// 'post-meta-fields': {
// _bg_advantages_home: [''],
// _bg_banner_home: ['35'],
// _bg_info_1_home: ['41'],
// _bg_info_2_home: [''],
// _bg_offers_home: ['38'],
// _bg_sales_home: ['36'],
// _bg_video_home: ['']
// }
// ...
// };
//Example below
<div class="banner_title DrukFont">{posts["post-meta-fields"]["_bg_sales_home"][0]}</div>
//meyby problem with parse incorrect parse json method
When you transforming the data you do the following:
const modifiedKey = key.replace('_','');
which makes the underscore _ dissapear from the front of your keys so _bg_sales_home will be undefined in your transformed object and accessing [0] on undefined will throw an error.
You have to use bg_sales_home:
<div class="banner_title DrukFont">{posts["post-meta-fields"]["bg_sales_home"][0]}</div>

react axios post generates json in array format. How to convert this to "name":"value" type format

const submitService = {
serviceType: this.state.serviceType,
dateOfService: this.state.dateOfService,
vehicleId: this.state.vehicleId,
orderNum: this.state.orderNum,
driverId: this.state.driverId,
vendorName: this.state.vendorName,
issueId: this.state.issueId
};
axios.post("http://localhost:8072/TruckyServiceMicroService/admin/services/saveService/", submitService)
.then(response => {
if (response.data != null) {
this.setState(this.initialState);
alert("Service Created Successfully");
}
});
This is the const forming the json and the post request sent using the const. On sending the post request through axios, it adds square braces in the json
initialState = {
serviceType: [], vehicleId: '', dateOfService: '', orderNum: '', driverId: '', vendorName: '', issueId: ''
}
This is the state
if you want a quick fix, change:
const submitService = {
serviceType: this.state.serviceType,
dateOfService: this.state.dateOfService,
vehicleId: this.state.vehicleId,
orderNum: this.state.orderNum,
driverId: this.state.driverId,
vendorName: this.state.vendorName,
issueId: this.state.issueId
};
to:
const keys = ["serviceType","dateOfService","vehicleId","orderNum","driverId","vendorName","issueId"]
const submitService = Object.entries(this.state).reduce((res, ([key, val])) => {
if(keys.includes(key))
res[key] = Array.isArray(val)?val[0]:val
return res
}, {})
this basically creates the payload with keys and values pairs of state but if the value is array type it just uses the first index of it.

Destructuring array and accessing the first element

I made and API call using fetch to get JSON data. That data is then passed to my function displayCartTotal, which accepts a parameter that uses de-structuring to obtain results.
In displayCartTotal, I want to de-structure the first item into the results array, into a data variable. Next, use object de-structuring to obtain the itemsInCart and buyerCountry properties of the data.
I have tried de-structuring the array, but is not working, also when i do typeof() on the data I receive, I get "object".
Here is format of the JSON data
{
results: [{
itemsInCart: [{
name: "Jolof Rice",
price: 80,
qty: 2
}, {
name: "Jolof Rice",
price: 80,
qty: 2
}],
buyerCountry: "Uganda"
}],
info: {
seed: "85e0e8ca0e095f74",
results: "1",
page: "1",
version: "0.1",
time: {
instruct: 11,
generate: 5
}
}
}
Code:
const displayCartTotal = ({results}) => {
const [data] = results;
const [itemsInCart,buyerCountry] = data;
return results;
};
const fetchBill = () => {
const api = 'https://randomapi.com/api/006b08a801d82d0c9824dcfdfdfa3b3c';
fetch(api)
.then(response => response.json())
.then(data => displayCartTotal(data))
.catch(error => console.error(error));
};
I expect to de-structure the first item in the results array into a data variable. And also to use object de-structuring to obtain the itemsInCart and buyerCountry properties of data.
Have you tried placing the nth position of the object
const displayCartTotal= ({results})=>{
const {0: data} = results;
const {itemsInCart, buyerCountry} = data;
}

Too tidious hooks when querying in REST. Any ideas?

I've just started using feathers to build REST server. I need your help for querying tips. Document says
When used via REST URLs all query values are strings. Depending on the service the values in params.query might have to be converted to the right type in a before hook. (https://docs.feathersjs.com/api/databases/querying.html)
, which puzzles me. find({query: {value: 1} }) does mean value === "1" not value === 1 ? Here is example client side code which puzzles me:
const feathers = require('#feathersjs/feathers')
const fetch = require('node-fetch')
const restCli = require('#feathersjs/rest-client')
const rest = restCli('http://localhost:8888')
const app = feathers().configure(rest.fetch(fetch))
async function main () {
const Items = app.service('myitems')
await Items.create( {name:'one', value:1} )
//works fine. returns [ { name: 'one', value: 1, id: 0 } ]
console.log(await Items.find({query:{ name:"one" }}))
//wow! no data returned. []
console.log(await Items.find({query:{ value:1 }})) // []
}
main()
Server side code is here:
const express = require('#feathersjs/express')
const feathers = require('#feathersjs/feathers')
const memory = require('feathers-memory')
const app = express(feathers())
.configure(express.rest())
.use(express.json())
.use(express.errorHandler())
.use('myitems', memory())
app.listen(8888)
.on('listening',()=>console.log('listen on 8888'))
I've made hooks, which works all fine but it is too tidious and I think I missed something. Any ideas?
Hook code:
app.service('myitems').hooks({
before: { find: async (context) => {
const value = context.params.query.value
if (value) context.params.query.value = parseInt(value)
return context
}
}
})
This behaviour depends on the database and ORM you are using. Some that have a schema (like feathers-mongoose, feathers-sequelize and feathers-knex), will convert values like that automatically.
Feathers itself does not know about your data format and most adapters (like the feathers-memory you are using here) do a strict comparison so they will have to be converted. The usual way to deal with this is to create some reusable hooks (instead of one for each field) like this:
const queryToNumber = (...fields) => {
return context => {
const { params: { query = {} } } = context;
fields.forEach(field => {
const value = query[field];
if(value) {
query[field] = parseInt(value, 10)
}
});
}
}
app.service('myitems').hooks({
before: {
find: [
queryToNumber('age', 'value')
]
}
});
Or using something like JSON schema e.g. through the validateSchema common hook.