I want to add a property to result query of realm and i did something like this
findAllSelected() {
let result = super.findAll()
result = result.map(item => {
return {...item, isSelected: false}
})
return result
}
This is my findAll method
findAll () {
return RealmSchemas.objects(this.schema)
}
But later i found it the result from findAll is looks like this
{"0": {"contact_id": 7, "id": 1, "isArchived": false, "isPinned":
true, "message": Test 1", "name": "User 1", "time": "14.10 PM", "unread": 1}, "1":
{"contact_id": 8, "id": 2, "isArchived": false, "isPinned": true,
"message": "Test 2", "name": "User 2",
"time": "11.21 AM", "unread": 2}}
My question is how do i add property to array likes that? Or other way around how do i convert result of my query to list of object so i can use map to add a property?
You may try using this:
let result = super.findAll()
for (const propertyName in result){
result[propertyName].isSelected = false
}
It gets all the property names in the object and adding a new property isSelected for each iteration.
Related
I am trying to get latest messages from table 'messages' for inbox
The chat is between user and owner of the item (listed on my portal)
I want to get unique data with item_id
My code is
public function inbox()
{
// $inbox = ChatMessage::distinct('item_id')->where('incoming_msg_id', auth()->user()->id)->orWhere('outgoing_msg_id', auth()->user()->id)->orderBy('msg_id', 'DESC')->get();
$inbox = Message::where('incoming_msg_id', auth()->user()->id)->orWhere('outgoing_msg_id', auth()->user()->id)->latest('msg_id')->get()->unique('item_id');
return $this->sendResponse($inbox,'Chat');
}
Result is perfect just i need is non-associative/non-object array.
Current output
{
"success": true,
"data": {
"0": {
"msg_id": 68,
"incoming_msg_id": 0,
"outgoing_msg_id": 2,
"msg": "ok let me check",
"msg_for": "hadiya",
"item_id": "13",
"msg_at": "1 day ago"
},
"1": {
"msg_id": 62,
"incoming_msg_id": 0,
"outgoing_msg_id": 2,
"msg": "test msg",
"msg_for": "hadiya",
"item_id": "1",
"msg_at": "2 days ago"
}
},
"message": "Chat"
}
Expected Output
{
"success": true,
"data": [
{
"msg_id": 68,
"incoming_msg_id": 0,
"outgoing_msg_id": 2,
"msg": "ok let me check",
"msg_for": "hadiya",
"item_id": "13",
"msg_at": "1 day ago"
},
{
"msg_id": 62,
"incoming_msg_id": 0,
"outgoing_msg_id": 2,
"msg": "test msg",
"msg_for": "hadiya",
"item_id": "1",
"msg_at": "2 days ago"
}
],
"message": "Chat"
}
It's simple by following approach you can set the http status code also (optional).
return response()->json(['chat' => $inbox], 200);
I got the solution after lots of revisions.
I got the distinct data in the best json format I was looking for...
$inbox = ChatMessage::select('msg_id','incoming_msg_id','outgoing_msg_id','msg','msg_for','item_id','msg_at')->groupBy('item_id')->where('incoming_msg_id', auth()->user()->id)->orWhere('outgoing_msg_id', auth()->user()->id)->get();
return $this->sendResponse($inbox,'Inbox');
Explanation : In Laravel 8 there is a function known as groupBy() which is use for getting distinct results.
Check the link here for more information.
below is part of my JSON response coming from an API
{
"totalCount": 2,
"customAttributes": [
{
"objectType": "OWNER",
"atrributeId": 215,
"attributeName": "DATELICENSEFIRSTISSUED",
"attributeDisplayName": "DATE LICENSE FIRST ISSUED",
"dataType": "DATE",
"inputValues": [],
"isGridEligible": "true",
"isInvoiceEligible": "false"
},
{
"objectType": "LOCATION",
"atrributeId": 217,
"attributeName": "DONOTRENEW",
"attributeDisplayName": "DO NOT RENEWS",
"dataType": "Value List",
"inputValues": [
{
"id": 5,
"value": "VEHICLELISTREQUIRED"
},
{
"id": 6,
"value": "STATESWITHRECIPROCITY"
}
],
"isGridEligible": "true",
"isInvoiceEligible": "false"
}
]
}
Here, I am binding customAttributes as grid data.
this.customFieldsService.getCustomFields(this.columnList, this.pageNumber, this.pageSize, null).subscribe(res => {
if(res){
this.cfData = res;
this.gridData = {
data: this.cfData.customAttributes,
total: this.cfData.totalCount
}
}
});
Here, my problem is with inputValues column, which comes as an array of objects. I need to convert it to comma seaparated values and then bind to grid data like
"inputValues": ["VEHICLELISTREQUIRED" "STATESWITHRECIPROCITY"]
I can ignore the "id" property as we are not using it at angular side. I tried using join method but not able to solve it within the nested array. Please suggest. Thanks.
In typescript it can be done with:
const joined: string = customAttribute.inputValues
.map(x => x.value) // [{value: 'VEHICLELISTREQUIRED'}, {value: 'STATESWITHRECIPROCITY'}]
.join(' ') // "VEHICLELISTREQUIRED" "STATESWITHRECIPROCITY"
const putIntoArray = [joined]; // ["VEHICLELISTREQUIRED" "STATESWITHRECIPROCITY"]
Of course you can put the joined string immediately into an array.
There is some list of elements in json format, it looks like this:
[{
'id': 0,
"name": "Category name1",
"services": [{
"id": 0,
"name": "Product name1"
}, {
"id": 1,
"name": "Product name2"
}]
},
{
'id': 1,
'name': "Category name2",
"services": [{
"id": 0,
"name": "Product name1"
}, {
"id": 1,
"name": "Product name2"
}]
}
]
I'm trying to get only the entire "services" array from the first category. Conditionally, I'm trying to get it as follows:
this.class = this.http.get('/assets/products.json');
this.class.forEach(element => {
if (element.id == ID) //The ID is obtained when calling the function in which this code is executed
{
console.log(element.services);
}
}
However, this gives me absolutely nothing and "undefined" is output to the console, however, with the same array and under the same conditions on the site https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach it (foreach and console.log) outputs everything I need.
//The same foreach only on the mozilla website
array1.forEach(item => {
if(item.id==1){ //1 вместо ID
console.log(item.services);
}});
Output to the console: Array [Object { id: 0, name: "Product name1"}, Object { id: 1, name: "Product name2"}].
P.S. I don't really need this list of products in the console, I'm trying to pass a variable, but since undefined is passed to the variable, as well as to the console, I can't use the variable and call it to display products on the page. All this is used in the typescript angular project.
The HttpClient methods like get return observables, to which you need to subscribe to in order for the request to even get executed. In your situation, the class property is only holding a reference to the observable returned by calling this.http.get. Try subscribing to the observable and use the result to extract the data that you need.
this.http.get<any[]>('/assets/products.json').subscribe((data) => {
this.class = data;
this.class.forEach((element) => {
if (element.id == ID) {
console.log(element.services);
}
});
});
I am using Typescript in an Angular/Ionic project. I have an array of users that contain an array of skills. I have to filter users based on their online status as well as skills.
[
{
"id": 1,
"name": "Vikram Shah",
"online_status": "Online",
"skills": [{
"id": 2,
"title": "CSS"
},
{
"id": 3,
"title": "JavaScript"
},
{
"id": 4,
"title": "Python"
}
]
},
{
"id": 1,
"name": "Abhay Singh",
"online_status": "Online",
"skills": [{
"id": 1,
"title": "HTML"
},
{
"id": 2,
"title": "CSS"
},
{
"id": 3,
"title": "JavaScript"
},
{
"id": 4,
"title": "Python"
}
]
},
{
"id": 1,
"name": "Test Oberoi",
"online_status": "Online",
"skills": [{
"id": 1,
"title": "HTML"
},
{
"id": 2,
"title": "CSS"
},
{
"id": 3,
"title": "JavaScript"
},
{
"id": 4,
"title": "Python"
}
]
}
]
This is how all skills look like
this.skill_types = [
{"id":8,"title":"Cleaner", checked:false},
{"id":7,"title":"Painter", checked:false},
{"id":6,"title":"Plumber", checked:false},
{"id":5,"title":"Carpenter", checked:false},
{"id":4,"title":"Advisor", checked:false},
{"id":3,"title":"Team Leader", checked:false},
{"id":2,"title":"Management", checked:false},
{"id":1,"title":"Administrator", checked:false}
];
This array contains the IDs of skills that I want to filter
filterArr = [1, 3, 6];
This solution is almost working as expected. It is filtering well based on two criteria together.But not sure how to add condition for second filtering. The second filter should apply only if filterArr is not empty.
return this.items = this.items.filter((thisUser) => {
return thisUser.online_status.toLowerCase().indexOf(onlineStatus.toLowerCase()) > -1 &&
thisUser.skills.some(c => this.filterArr.includes(c.id))
});
The issue I am facing with code above is When there is no skill selected in the filter criteria, I would like to display all users. But it is not working that way. The logic here is to not apply any filter when the size of selected skills (filter condition) is greater than zero. So I tried this way....which looks similar to the way above...but this makes everything worse.
let filteredByStatus = [];
filteredByStatus = this.items.filter((thisUser) => {
return thisUser.online_status.toLowerCase().indexOf(onlineStatus.toLowerCase()) > -1
});
//Condition can be applied if filtering is separated
let filteredBySkills = [];
filteredBySkills = this.items.filter((thisUser) => {
return thisUser.skills.some(c => this.filterArr.includes(c.id))
});
//Expecting to join results from multiple filters
return this.items = filteredByStatus.concat(filteredBySkills);
But this is not working at all. Not sure what wrong is there. I am looking for a solution that enables to join arrays of similar objects without duplicating them.
Don't think you need to join arrays for your filtering. You can use something like rxjs filter.
return from(this.items)
.pipe(
filter(user => {
return user.online_status.toLowerCase().indexOf(onlineStatus.toLowerCase()) > -1
&& user.skills.some(c => filterArr.includes(c.id));
})
);
Or if you like to split it up you can just change it to like:
return from(this.items)
.pipe(
filter(user => user.online_status.toLowerCase().indexOf(onlineStatus.toLowerCase()) > -1),
filter(user => user.skills.some(c => filterArr.includes(c.id)))
);
Stackblitz: https://stackblitz.com/edit/angular-pk3w8b
You can tweak your condition a bit and place !this.filterArr.length in your condition (in terms of OR condition AND with user status) to make your whole condition gets true so that user gets filter.
I have below JSON and wanted to update the value depending on Aid, Bid and Cid using Immutable.js
e.g.
Below input provided.
Aid= A, Bid = 1, Cid= 4, NewValue = 'FOUR'
If above input is provided the value "One" needs to be changed to "FOUR"
let sampleJson = {
Aid: 'A', detail:"sample", list: [
{
"Bid": "1",
"group": [
{
"name": "Group A",
"Cid": "4",
"value": "One"
},
{
"name": "Group A",
"Cid": "41",
"value": "1"
},
]
},
{
"Bid": "2",
"group": [
{
"name": "Group A",
"Cid": "4",
"value": "1"
},
{
"name": "Group A",
"Cid": "4",
"value": "1"
},
]
};
I was able to access the value using below code. How can i return the entire JSON with updated value?
let variale = Immutable.fromJS(sampleJson).
getIn(['list']).
find(allocation => allocation.get("Bid") === "1").
getIn(['group']).
find(fun => fun.get("Cid") === "4").set('value',"FOUR");
Anyone has any suggestions on how to resolve this problem?
I think you can try to do this like so:
let immutable = Immutable.fromJS(sampleJson);
immutable = immutable.setIn(['list', 0, 'group', 0, 'value'], 'FOUR');
This monstrosity is how I would do it:
const newData = originalData.update('list', list => {
const itemIndex = list.findIndex(item => item.get('Bid') === '2');
return list.update(itemIndex, listItem => {
return listItem.update('group', groupList => {
const groupIndex = list.findIndex(group => group.get('Cid') === '4');
return groupList.update(groupIndex, group => {
return group.set('value', 'FOUR');
});
});
});
});
https://jsbin.com/latupo/7/edit?html,js,console
Personally I stopped using Immutable, I always found it a bit painful (not to mention those docs!). I now use redux and good old cloning to not mutate state. Less performant in theory but if you've got nothing that runs over a few milliseconds anyway, save yourself the trouble...