Automapper Custom mapping or ignore - automapper

I have tried something similar to AutoMapper Custom Mappings
however, what i really want is to not map to another property but ignore it.
i have tried:
.ForMember(m=>m.BillingAddress,m=>m.ResolveUsing((result, card) => {
if (!string.IsNullOrEmpty(card.BillingDetails?.Address1)) {
return card.BillingDetails.Address1;
}
else {
return result.Ignore();
}
}))
but this just sets some type of resolution result to the property i'm trying to map to.
What i'd really like to do is what I attempted to ask in this issue:
https://github.com/AutoMapper/AutoMapper/issues/1690
i.e.
.ForMember(m=>m.BillingAddress, m=>{
m.Condition(s=>!String.IsNullOrEmpty(s.BillingDetails?.Address1), m.MapFrom(...), m.Ignore())
}
right now it's nulling out anything i have in those fields if i use the .condition
and a .MapFrom after it.

This isn't really how i'd like this to work, but it worked for this particular situation. It would still be nice to have what i wanted before but it looks like if you don't do a mapFrom at all it simply ignores it.
.ForMember(m => m.BillingAddress, m => {
m.Condition(s => !String.IsNullOrEmpty(s.BillingDetails?.Address1));
m.MapFrom(i => i.BillingDetails.Address1);
})
.ForMember(m => m.BillingAddress2, m => {
m.Condition(s => !String.IsNullOrEmpty(s.BillingDetails?.Address2));
m.MapFrom(i => i.BillingDetails.Address2);
})
.ForMember(m => m.City, m => {
m.Condition(s => !String.IsNullOrEmpty(s.BillingDetails?.City));
m.MapFrom(i => i.BillingDetails.City);
})
.ForMember(m => m.State, m => {
m.Condition(s => !String.IsNullOrEmpty(s.BillingDetails?.State));
m.MapFrom(i => i.BillingDetails.State);
})
.ForMember(m => m.Zip, m => {
m.Condition(s => !String.IsNullOrEmpty(s.BillingDetails?.Zip));
m.MapFrom(i => i.BillingDetails.Zip);
})

Related

Laravel import excel error Undefined offset: 1

I tried to import excel to my mySql DB and am facing this error Undefined offset: 1
I have search everywhere, no related answers could resolve mine.
Here is my model
public function model(array $row)
{
return new Medicine([
'name' => $row[0],
'dosage_form' => $row[1],
'dosage_strength' => $row[2],
'product_date' => $row[3],
'expire_date' => $row[4],
'unit' => $row[5],
'serial_no' => $row[6],
]);
my Controller
public function import()
{
Excel::import(new MedicineImport, storage_path('Book1.xlsx'));
return redirect('Subscriber/importExcel')->with('success', 'All good!');
}
here is my excel screenshot
Have you tried doing a
var_dump($row)
and see if all the indices are properly set (especially index 1)?

What's the difference between Promise.reject an error and Promise.reject object?

I was reading some nodejs tutorial which talks about rejection in nodejs. They say that it's best practice to reject an error instead of a string or an plain text. Taking example of this code.
This is a example of rejecting a string
function cookMeat(chef){
grillMeat(chef)
.then(meat => {
if(chef.isTired){
return Promise.reject(chef.tiredReason);
}
return Promise.resolve(meat);
})
}
function cookNoodle(cheif){
boilNoodle(chef)
.then(noodle => {
if(chef.isTired){
return Promise.reject(chef.tiredReason);
}
return Promise.resolve(noodle);
})
}
function cook(){
let chef
prepareFood()
.then(c => {
chef = c;
return true;
})
.then(() => cookMeat(chef))
.then(() => cookNoodle(chef))
.catch(err => {
state: Fail,
reason: error
})
.then(res => {
state:Ready
})
}
cook()
.then((res) => serveCustomer(res))
And this is a example of rejecting an error
function cookMeat(chef){
grillMeat(chef)
.then(meat => {
if(chef.isTired){
return Promise.reject(new Error(chef.tiredReason));
}
return Promise.resolve(meat);
})
}
function cookNoodle(cheif){
boilNoodle(chef)
.then(noodle => {
if(chef.isTired){
return Promise.reject(new Error(chef.tiredReason));
}
return Promise.resolve(noodle);
})
}
function cook(){
let chef
prepareFood()
.then(c => {
chef = c;
return true;
})
.then(() => cookMeat(chef))
.then(() => cookNoodle(chef))
.catch(err => {
state: Fail,
reason: error.message
})
.then(res => {
state:Ready
})
}
cook()
.then((res) => serveCustomer(res))
Since I want to use reject to skip part of the promise chain. So I am wondering if there are any difference?
wPromise rejections are similar to throwing exceptions / error objects.
There are two rules that apply to throwing exceptions that apply here too:
In javascript, it's better to throw an Error object. Among other things, you will get stack information. It's also what most people expect when using a javascript code base.
Don't use exceptions for flow-control
The second one is such a common advice, you can google it verbatim and learn more. You're using Promise rejections as flow control and this is a bad idea.
Your functions can be rewritten a bit though. This is even better:
function cookMeat(){
grillMeat()
.then(meat => {
if(meat.isRaw){
throw new Error(meat.rawReason);
}
return meat;
});
}
function cookNoodle(){
boilNoodle()
.then(noodle => {
if(noodle.isRaw){
throw new Error(noodle.rawReason);
}
return noodle;
})
}
function cook(){
return prepareFood()
.then(() => cookMeat())
.then(() => cookNoodle())
.catch(err => {
state: Fail,
reason: error.message
})
.then(res => {
state:Ready
})
}
cook()
.then((res) => talkWithCustomer(res))
I got rid of your Promise.reject and Promise.resolve statements, because they are unneccary from within a then() function. The advice to use them only really applies 'outside' of then() chains.

return multiple queries from backend

Straight forward: I have a backend with multiple routes.
Is it possible to return multiple queries from one route, e.g.:
router.get("/test/:id", (req, res) => {
example.find({test: req.params.id})
.then(data => res.json(data.map(moreData => moreData.serialize()))
differentExample.find({something: req.params.id})
.then(data => res.json(data.map(moreData => moreData.serialize()))
})
And then have both finds/results in the front-end:
.then(res => {
if (!res.ok) {
return Promise.reject(res.statusText);
}
return res.json();
})
.then(data => console.log(data))
I found that if I user Promise.all() I use the result of the first query for the query parameters of the second. The above is just my thought process. It doesn't work like this and I am missing the piece that makes it happen (if it's possible)
You can't send multiple responses using HTTP. HTTP requests to responses are 1:1 so when a request is sent you will ALWAYS expect only one response. Anything else and it would get quickly messy. So, how to send multiple sets of data?
You could do something like this:
router.get("/test/:id", (req, res) => {
let result = {}
example.find({test: req.params.id})
.then(data => {
result['partOne'] = data.map(moreData => moreData.serialize())
return differentExample.find({something: req.params.id})
}).then(data => {
result['partTwo'] = data.map(moreData => moreData.serialize())
res.json(result)
})
}
Note: I haven't tested any of this code. But in essence, do both requests, and once you have the result of both requests you can return the result. If the requests don't depend on each other, you could use something like this using Promise.all as you mentioned:
Promise.all(
example.find({test: req.params.id},
differentExample.find({something: req.params.id})
).then(result => {
res.json(result);
})

Promises and condition from async call

I'm implementing my service using Node.js with AWS DynamoDB (aws-sdk).
It's unclear for me how to implement the following scenario with promises:
I get a request to modify an entity with specified attributes
I'm trying to find the entity in the DB (async call find)
If the entity not found then create one with initial state (async call createInitialStateObject)
Modify the entity (which was in the DB before or just created on step 3) according to specific rules (async call applyModifications)
This is my first attempt:
function scenario(params) {
find(params).then((data) => {
let objectExists = checkExistense(data);
if (!objectExists) {
createInitialStateObject(params).then((data) => {
console.log("Object created");
// OK
}).catch((err) => {
console.error("Object not created");
// exit and return error
});
}
applyModifications(params).then((data) => {
// OK, return data
}).catch((err) => {
// exit and return error
});
}).catch((err) => {
// exit and return error
});
}
But the flaw here is that creation could happen before the modification, it's not bound to happen one after another.
The other attempt works, but looks a bit weird. I create an empty promise to call in case the object already exists:
function scenario(params) {
find(params).then((data) => {
let conditionalPromise = new Promise((resolve) => {
resolve(null);
});
let objectExists = checkExistense(data);
if (!objectExists) {
conditionalPromise = createInitialStateObject(params);
}
conditionalPromise.then((data) => {
applyModifications(params).then((data) => {
// OK, return data
}).catch((err) => {
// exit and return error
});
}).catch((err) => {
// exit and return error
});
}).catch((err) => {
// exit and return error
});
}
How it should be implemented in a right way?
Creating 'empty' or sync. Promises isn't unusual. There is even a short way of doing that: Promise.resolve(value) creates and resolves a Promise immediately.
Besides that you should make use of proper chaining and stop nesting things so much. Once you are in a chain, you don't even need to resolve an empty promise as a return value of a non thenable object is interpreted as exactly this.
function scenario(params) {
return find(params)
.then(data => {
let objectExists = checkExistense(data);
if (!objectExists) {
return createInitialStateObject(params);
}
// if we return nothing (or null in your case) this will be the same as return Promise.resolve()
return null;
})
.then(data => applyModifications(params))
.then(data => console.log(data))
.catch(err => console.log(err));
// exit and return error
}

Node js db2 module

I'm using that code
var ibmdb = require('ibm_db')
function executeSql(sql)
{
return new Promise( (resolve,reject) => {
ibmdb.open("DRIVER={DB2};DATABASE=SITRAN;...",(err,conn) => {
if (err) reject(Error(err))
conn.query(sql,(err,rows) => {
if (err) reject(Error(err))
console.log('length:',rows.length)
conn.close(() => { console.log('done'); resolve(rows); })
})
})
})
}
executeSql(sql)
.then((result) => { console.log('result:',result.length) })
The db2 part is working, it gives 1045 rows but the code is working strangely
length: 0
length: 1045
done
result: 0
I don't understand why length is displayed twice, one with 0 and one with 1045. And also why the resolve(rows) seems not working.
conn.query() is an asynchronous function which might explain the double console.log() behavior. As far as the weird behavior with resolve(), try resolve(rows.fetchAllSync()) instead.

Resources