I'm using useSelector to retrieve my store. However when I console.log(items) there is data but when I do this console.log(items.totalAmount) I get undefined.
import {useSelector} from 'react-redux';
const items = useSelector(state => state.items);
//I'm able to see the data
console.log(items)
The data when its logged
[{"code": "SR71", "description": "Keyboard", "quantity": 1, "selling_price": 166.99, "totalAmount": 166.99}, {"code": "10", "description": "Cement", "quantity": 7, "selling_price": 20, "totalAmount": 140}]
//I get undefined
console.log(items.totalAmount);
Could any please explain what am I doing wrong.
items looks like this when you do console.log:
[
{..., "totalAmount": 166.99},
{..., "totalAmount": 140},
...
]
So you can access totalAmount of each items like: items[0].totalAmount
And for getting the totalAmount of all items, you can use:
let sum = Array.from(items).reduce((acc, cur) => acc + cur.totalAmount, 0)
Also i used Array.from since there is no guaranty for items to be a serializable (normal) array. (as you confirmed that it was non-serializable .)
Related
I have a question about mapping an array of ID's (inputdata) and returning all related documents to those ID's. I have a UDF set up to retrieve the documents for a single ID and was hoping some tweaking would make that work. I can't seem to figure out how to map over the inputdata and create a variable (data:) to store the new array of documents. Any help is appreciated. Here is the single entry UDF which works:
Query(
Lambda(
["inputdata"],
Let(
{
data: Map(
Paginate(
Match(
Index("certificate_by_dealer"),
Ref(Collection("Dealers"), Select("dealer", Var("inputdata")))
)
),
Lambda(["ref"], Get(Var("ref")))
)
},
Select(["data"], Var("data"))
)
)
)
Is there a simple...or any solution to make this work for an array of ID's as inputdata?
Call function is:
Call("user_dealers_all_certificates", {
ids: [301393590798516736, 301393590798516749]
}
Unfortunately I get no results. (Adding quotes solved the issue)
Here is implementing the suggested UDF:
Query(
Lambda(
["inputdata"],
Let(
{ dataIds: Select("ids", Var("inputdata")) },
Union(
Map(
Var("dataIds"),
Lambda(
["id"],
Select(
["data"],
Paginate(
Match(
Index("certificate_by_dealer"),
Ref(Collection("Dealers"), Var("id"))
)
)
)
)
)
)
)
)
)
Adding quotes created a proper response:
Call("user_dealers_all_certificates", {ids: ["302122229239382536", "301394099049595400"]})
[
Ref(Collection("Certificate"), "302122488174739977"),
Ref(Collection("Certificate"), "302120872550859273")
]
However the GraphQL query returns bad data:
query {
allUserDealersCertificate(data: {ids: ["302122229239382536", "301394099049595400"]}){
data {
_id
}
}
}
response:
{
"errors": [
{
"message": "Lambda expects an array with 1 elements. Array contains 4.",
"extensions": {
"code": "invalid argument"
}
}
]
}
GraphQL error without paginated: true in schema:
{
"data": {
"allUserDealersCertificate": [
null,
null
]
},
"errors": [
{
"message": "Cannot return null for non-nullable type (line 3, column 5):\n _id\n ^",
"path": [
"allUserDealersCertificate",
0,
"_id"
],
"locations": [
{
"line": 3,
"column": 5
}
]
},
{
"message": "Cannot return null for non-nullable type (line 3, column 5):\n _id\n ^",
"path": [
"allUserDealersCertificate",
1,
"_id"
],
"locations": [
{
"line": 3,
"column": 5
}
]
}
]
}
Based on the query you provided, I feel the need to point out that the Match function performs exact matches. It does not (and cannot) unroll a structured array for you. Neither can the Ref function.
You'd need to call Map on the inputdata, and get results for each id. Then you can Union those results together into a single list.
I don't know the exact shape of the data that you're dealing with, so here's a query that works with the pre-populated data available in the Dashboard:
Let(
{
// the pre-populated data has 3 stores, with ids 301, 302, and 303
// here, we want the products in stores 301 and 302
ids: [ 301, 302 ]
},
// this is where we combine all of the results
Union(
Map(
// here is where we loop over the list of ids
Var("ids"),
Lambda(
// for each id, run this function's expression
"id",
Select(
// each Paginate call returns a page of results with its own data
// field, so we have to select those out
"data",
Paginate(
Match(
Index("products_by_store"),
// here we compose a reference to a specific store, using the
// Lambda function's current id
Ref(Collection("stores"), Var("id"))
)
)
)
)
)
)
)
Npte that I've used Let to simulate passing an array to the body of a UDF. When you run this query, the result should be:
[
["avocados", "Conventional Hass, 4ct bag", 3.99],
["cilantro", "Organic, 1 bunch", 1.49],
["limes", "Conventional, 1 ct", 0.35],
["limes", "Organic, 16 oz bag", 3.49],
["cups", "Translucent 9 Oz, 100 ct", 6.98],
["pinata", "Giant Taco Pinata", 23.99],
["pinata", "Original Classic Donkey Pinata", 24.99]
]
I'm working with an existing mssql database, where I'm not able to make any changes. Trying to make an API using Flask and Marshmallow. I have some issues deserializing the following query returning all people working on a project.
query = (
sa.session.query(Employee, sa.func.sum(JobEntry.number_registered).label("total"))
.join(JobEntry, Employee.employee_hashkey==JobEntry.employee_hashkey)
.filter(JobEntry.project_number==f'{project_number}')
.group_by(Employee)
).limit(3).all()
The query returns
print(query)
[(<Employee 188ED6A858997A48FDA53A404779A16F>, 229.0), (<Employee 1D40AB9C2A973C2BD33B1EF6108D2A70>, 2.0), (<Employee 38584E42E883131DC35151E4922A8094>, 176.75)]
The Employee contains the name, id, etc. How would I create a marshmallow schema returning, the following example.
[
{"name": "somename a", "total" 229.0, "id": 11},
{"name": "somename b", "total" 2.0, "id": 22},
{"name": "somename c", "total" 176.75, "id": 33}
]
Being a noob, I have experimented a bit... The following code returns almost what I want. But I get "Employee." in my keys ...
class ProjectUsersSchema(Schema):
class Meta:
model = Employee
fields = (
"Employee.name",
"Employee.id"
"total"
)
# returns "[{"Employee.name": "somename a", "total" 229.0, "Employee.id": 11}, ..."
Made a temporary f#ckly fix using nested schemas by including .split(".")[-1] into my snake_case to PascalCase schema
def pascalcase(s):
part_lst = s.split(".")[-1].split("_") # todo fix split(".")[-1]
if len(s) <= 2:
return "".join(i.upper() for i in part_lst)
else:
return "".join(i.title() for i in part_lst)
class PascalCaseSchema(ma.SQLAlchemyAutoSchema):
def on_bind_field(self, field_name, field_obj):
field_obj.data_key = pascalcase(field_obj.data_key or field_name)`
i want to get data from nested json.
My json looks like as given below
{
"id": 2,
"cover_image": "http://13.233.31.123/media/homepage-banner.jpg",
"name": " Website",
"tagline": " IT Right",
"status": "ACTIVE",
"client_name": "Company",
"start_date": null,
"end_date": null,
"technology_frontend": "HTML, CSS, JAVASCRIPT\r\nCMS: WORDPRESS",
"technology_backend": "PHP",
"description": "We provide robust and high quality Custom Web Development.\r\nCodism is a global technology and business services consulting firm. We are specialized in servicing business market needs specializing in Web Design and Development, Online marketing and IT Consulting Services to commercial and government customers. We provide staffing and end-to end consulting services for organizations.",
"gallery": [
{
"project": 2,
"image": "http://localhost/media/gallery_image/homepage-banner.jpg"
},
{
"project": 2,
"image": "http://localhost/media/projects/gallery_image/software-development.jpg"
},
{
"project": 2,
"image": "http://localhost/media/projects/gallery_image/New_FRS_Image_Mobile_app_development.jpg"
}
]
}
I want to get all the images of gallery. I am not getting how i can do that if i am doing console.log(this.state.gallery[0]) it is showing first object but while i am doing console.log(this.state.gallery[0].image) giving error. my i found somewhere like use state as given gallery: {
images: []
} so my state is like this. how should i use map to get all details please help. thanks in advance
I hope you are doing mistake while setState
your state should be like
this.state = { data : {} }
when you setState on componentDidMount or anywhere so do something like
this.setState({ data : jsonData )};
after that you can use data on your render method for rendering the images.
this.state.data.galley.map(item => <Image source={{item.image}/>);
if your jsonData is an array and you want to render first object of array so do like
this.state = {data: []};
this.setState({data:jsonData)};
this.state.data[0].galley.map(item => <Image source={{item.image}/>);
if your jsonData is an array and you want to render all nested images so do like this.
this.state = {data: []};
this.setState({data:jsonData)};
this.state.data.map(data => data.galley.map(item => <Image source={{item.image}/>));
If you want to have all the images of your state, you can do something like this.
When you use the setState, you can try setState({...yourJson}) to create a new object of your json in your state.
Try to parse the JSON first like
.then((responseData) => {
newData = JSON.parse(responseData);
this.setState({ data: newData });
this.setState({ ... newData.gallery });
})
I have an array of objects from which I need to pass each object separately into async method (process behind is handled with Promise and then converted back to Observable via Observable.fromPromise(...) - this way is needed because the same method is used in case just single object is passed anytime; the process is saving objects into database). For example, this is an array of objects:
[
{
"name": "John",
...
},
{
"name": "Anna",
...
},
{
"name": "Joe",,
...
},
{
"name": "Alexandra",
...
},
...
]
Now I have the method called insert which which inserts object into database. The store method from database instance returns newly created id. At the end the initial object is copied and mapped with its new id:
insert(user: User): Observable<User> {
return Observable.fromPromise(this.database.store(user)).map(
id => {
let storedUser = Object.assign({}, user);
storedUser.id = id;
return storedUser;
}
);
}
This works well in case I insert single object. However, I would like to add support for inserting multiple objects which just call the method for single insert. Currently this is what I have, but it doesn't work:
insertAll(users: User[]): Observable<User[]> {
return Observable.forkJoin(
users.map(user => this.insert(user))
);
}
The insertAll method is inserting users as expected (or something else filled up the database with that users), but I don't get any response back from it. I was debugging what is happening and seems that forkJoin is getting response just from first mapped user, but others are ignored. Subscription to insertAll does not do anything, also there is no any error either via catch on insertAll or via second parameter in subscribe to insertAll.
So I'm looking for a solution where the Observable (in insertAll) would emit back an array of new objects with users in that form:
[
{
"id": 1,
"name": "John",
...
},
{
"id": 2,
"name": "Anna",
...
},
{
"id": 3,
"name": "Joe",,
...
},
{
"id": 4,
"name": "Alexandra",
...
},
...
]
I would be very happy for any suggestion pointing in the right direction. Thanks in advance!
To convert from array to observable you can use Rx.Observable.from(array).
To convert from observable to array, use obs.toArray(). Notice this does return an observable of an array, so you still need to .subscribe(arr => ...) to get it out.
That said, your code with forkJoin does look correct. But if you do want to try from, write the code like this:
insertAll(users: User[]): Observable<User[]> {
return Observable.from(users)
.mergeMap(user => this.insert(user))
.toArray();
}
Another more rx like way to do this would be to emit values as they complete, and not wait for all of them like forkJoin or toArray does. We can just omit the toArray from the previous example and we got it:
insertAll(users: User[]): Observable<User> {
return Observable.from(users)
.mergeMap(user => this.insert(user));
}
As #cartant mentioned, the problem might not be in Rx, it might be your database does not support multiple connections. In that case, you can replace the mergeMap with concatMap to make Rx send only 1 concurrent request:
insertAll(users: User[]): Observable<User[]> {
return Observable.from(users)
.concatMap(user => this.insert(user))
.toArray(); // still optional
}
I am developing a web app using Codeigniter and MongoDB.
I am trying to get the map reduce to work.
I got a file document with the below structure. I would like to do a map reduce to
check how many times each tag is being used and output it to the collection files.tags.
{
"_id": {
"$id": "4f26f21f09ab66c1030d0000e"
},
"basic": {
"name": "The filename"
},
"tags": [
"lorry",
"house",
"car",
"bicycle"
],
"updated_at": "2012-02-09 11:08:03"
}
I tried this map reduce command but it does not count each individual tag:
$map = new MongoCode ("function() {
emit({tags: this.tags}, {count: 1});
}");
$reduce = new MongoCode ("function( key , values ) {
var count = 0;
values.forEach(function(v) {
count += v['count'];
});
return {count: count};
}");
$this->mongo_db->command (array (
"mapreduce" => "files",
"map" => $map,
"reduce" => $reduce,
"out" => "files.tags"
)
);
Change your Map function to:
function map(){
if(!this.tags) return;
this.tags.forEach(function(tag){
emit(tag, {count: 1});
});
}
Yea, this map/reduce simply calculate total count of tags.
In mongodb cookbook there is example you are looking for.
You have to emit each tag instead of entire collection of tags:
map = function() {
if (!this.tags) {
return;
}
for (index in this.tags) {
emit(this.tags[index], 1);
}
}
You'll need to call emit once for each tag in the input documents.
MongoDB documentation for example says:
A map function calls emit(key,value) any
number of times to feed data to the reducer. In most cases you will
emit once per input document, but in some cases such as counting tags,
a given document may have one, many, or even zero tags.