Why is my backbone.js collection not loading the correct list of data? - backbone.js

Here is my model and collection definition:
let PhotoModel = Backbone.Model.extend({
urlRoot: '/api/Photo',
defaults: {
id: "2",
import_id: "1",
original_filename: "",
filename: "IMG_8199 - Version 2.jpg",
aws_url: "https://s3.amazonaws.com/nakamoto.ca",
aws_bucket: "nakamoto.ca",
aws_s3_source_path: "source/2016/02/IMG_8199_-_Version_2.jpg",
aws_s3_compressed_path: "compressed/2016/02/IMG_8199_-_Version_2.jpg_1600x1200",
aws_s3_thumb_path: "thumb/2016/02/IMG_8199_-_Version_2.jpg_400x400",
capture_date: "2016-02-27 18:45:02",
upload_date: "2017-04-18 21:26:59",
file_size: "2026722",
width: "3264",
length: "2448",
camera_make: "Apple",
camera_model: "iPhone 6 Plus",
software: "Aperture 3.6",
latitude: "45.225206",
lat_ref: "N",
longitude: "45.292572",
lon_ref: "W",
altitude: "0.000000",
apple_note: "iPhone 6 Plus back camera 4.15mm f/2.2",
iptc_headline: "",
iptc_caption: "",
iptc_credit: "",
iptc_rating: "0",
iptc_city: "",
iptc_province_state: "",
iptc_country: "",
iptc_tags: "",
favorite: "0",
checksum: "4749e94d3eec7b6bf6a0136d8dc3457c",
public_flag: "0",
raw_exif: ""
},
parse: function(response_data) {
return response_data.data;
}
});
let PhotoCollection = Backbone.Collection.extend({
url: '/api/Photo',
model: PhotoModel,
parse: function(response_data) {
return response_data.data;
}
});
and here is the output from calling /api/Photo (copy and pasted from Chrome inspector):
{model: null, id: null, request: "GET", status: 1,…}
model: null
id: null
request: "GET"
status: 1
message: "grabbed some records with: SELECT * FROM `photo` WHERE 1 LIMIT 1, 10"
count: 10
page: 1
per_page: 10
data: [{id: "2", import_id: "1", original_filename: "", filename: "IMG_8199 - Version 2.jpg",…},…]
0: {id: "2", import_id: "1", original_filename: "", filename: "IMG_8199 - Version 2.jpg",…}
1: {id: "3", import_id: "1", original_filename: "", filename: "IMG_8192 - Version 2.jpg",…}
2: {id: "4", import_id: "1", original_filename: "", filename: "IMG_7961 - Version 2.jpg",…}
3: {id: "5", import_id: "1", original_filename: "", filename: "IMG_8086 - Version 2.jpg",…}
4: {id: "6", import_id: "1", original_filename: "", filename: "IMG_7947 - Version 2.jpg",…}
5: {id: "7", import_id: "1", original_filename: "", filename: "IMG_8113 - Version 2.jpg",…}
6: {id: "8", import_id: "1", original_filename: "", filename: "IMG_8009 - Version 2.jpg",…}
7: {id: "9", import_id: "1", original_filename: "", filename: "IMG_8109 - Version 2.jpg",…}
8: {id: "10", import_id: "1", original_filename: "", filename: "IMG_7967 - Version 2.jpg",…}
9: {id: "11", import_id: "1", original_filename: "", filename: "IMG_8004.jpg",…}
and here is my test code:
$(function() {
var photo_album = new PhotoCollection();
photo_album.fetch({
success: function (photo_album, response) {
photo_album.each(function(photo, index, all) {
console.log(photo.get('filename'));
});
}
);}
};
When I look in the console I see the same filename repeated 10 times, and it is the default filename from my Photo model (IMG_8199 - Version 2.jpg). I expect to see 10 different filenames as per the data returned by /api/Photo (above).
Can anyone tell me where I am going wrong? I feel like this must be something really obvious - this is my first attempt at backbone.js.
If I log the response_data.data in the Parse method of the collection, I see the correct data array from the json data.
Incidentally, I am able to successfully load individual Photo models without any problems.
Any help would be greatly appreciated, thanks!

From change log of 0.9.9
After fetching a model or a collection, all defined parse functions will now be run. So fetching a collection and getting back new models could cause both the collection to parse the list, and then each model to be parsed in turn, if you have both functions defined.
Chances are your individual model fetch succeeds because of proper response structure from the server, but the collection fetch response passed to model's parse is simply an object like this:
{id: "3", import_id: "1", original_filename: "", filename: "IMG_8192 - Version 2.jpg",…}
which doesn't have a data property, so
parse: function(response_data) {
return response_data.data;
}
in the model will return undefined, leaving default values in the newly created model. You have to update the model parse to take care of both cases

Related

Picking a random element from Swift Class

This is a model of my makeshift database
var categories: [Category] = [
Category(name: "X",
sign: [Sign(code: "X-1", name: "***", description: "", picture: ""),
Sign(code: "X-2", name: "***", description: "", picture: "")]),
Category(name: "Y",
sign: [Sign(code: "Y-1", name: "Yyy", description: "", picture: ""),
Sign(code: "Y-2", name: "yyy", description: "", picture: "")]),
Category(name: "Z",
sign: [Sign(code: "Z-1", name: "Zzz", description: "", picture: ""),
Sign(code: "Z-2", name: "ZZZ", description: "", picture: "")])
]
I need to get one random element of any category (not one from each) from this base and print it as sign.code
I prepared the variable to store the value:
var RandomSign: Sign
And tried to do it with for loop:
func randomSign() {
for categorie in categories {
randomSign = categorie.sign.randomElement()
But, in the result, my loop generate me random element from each category, and finally save only random from the last one. I would like print for example "X-2" in my consol as random selected value.
Why not pick a random category and then a random sign from that random category?
func randomSign() {
randomSign = categories.randomElement()!.sign.randomElement()!
}
This code will crash if any of the arrays are empty. It would be safer if randomSign was optional then you can do:
func randomSign() {
randomSign = categories.randomElement()?.sign.randomElement()
}
Or you could fallback to a default Sign:
func randomSign() {
randomSign = categories.randomElement()?.sign.randomElement() ?? Sign(code: "empty", name: "***", description: "", picture: "")
}

Display specific flastlist items with specific keys

my data :
const DATA = [
{
id: "1",
from: "Canada",
name: "person1",
},
{
id: "2",
from: "Canada",
name: "person2",
},
{
id: "3",
from: "France",
name: "person3",
}];
i need to filter this flatList and only display people from Canada
I think you are looking for something like:
const result = DATA.filter(element=> element.from === "Canada")
Then you can use your result to display it in the format that you want.

Mongo database call returning incorrect data after reload

I am trying to sort some database entries based on a boolean representing if a job is "completed" or not. The mutation functionality is working every time according to the graphQL playground but when the database call is utilized in the application the boolean data console logs as true first but then quickly logs again as false. The playground returns the data as true every time, once it has been changed, but something inside the application is not playing nice. Me and my project partners are freshly out of a coding bootcamp and have been learning successfully at a pretty steady pace but have not been able to figure this one out. Any feedback is appreciated. Thanks!!
const { loading: userLoading, data } = useQuery(QUERY_ME_BASIC);
const { loading: jobsLoading, data: jobsData } = useQuery(GET_JOBS);
var user = {};
var jobs = [];
var completedJobs = [];
var incompleteJobs = [];
if (!userLoading) {
console.log(jobsData)
user = data.me;
}
if(!jobsLoading){
jobs = jobsData.jobs
}
if(jobs){
console.log(jobs)
for (let i = 0; i < jobs.length; i++) {
if (jobs[i].completed === false) {
incompleteJobs.push(jobs[i]);
}
}
}
Query Response (GET_JOBS) from Graphql playground
{
"data": {
"jobs": [
{
"id": "47",
"_id": "6107fce77f7afc40e4e185a7",
"date": "2021-08-17",
"category": "Yard Waste",
"description": "addas",
"distance": "1.585",
"taken": true,
"completed": true,
"phone": "6153050246",
"email": "wfh2d88#gmail.com",
"driverEmail": "wfh2d88#gmail.com",
"createdAt": "Aug 2nd, 2021 at 9:10 am",
"pickup": {
"address": "207 Porter Village Circle",
"address2": "A",
"city": "Nashville",
"state": "Tennessee",
"zip": "37206",
"lat": "36.182571",
"lng": "-86.733267"
},
"dropoff": {
"address": "1800 Stratford Ave",
"address2": "A",
"city": "Nashville",
"state": "Alabama",
"zip": "37206",
"lat": "36.198164",
"lng": "-86.717083"
}
}
]
}
}
console.log(job) after Job Completion (3 appear one quickly after the other). First Two:
0:
category: "Yard Waste"
completed: true
createdAt: "Aug 2nd, 2021 at 9:10 am"
date: "2021-08-17"
description: "addas"
distance: "1.585"
driverEmail: "wfh2d88#gmail.com"
dropoff: {address: "1800 Stratford Ave", address2: "A", city: "Nashville", state: "Alabama", zip: "37206", …}
email: "wfh2d88#gmail.com"
id: "47"
phone: "6153050246"
pickup: {address: "207 Porter Village Circle", address2: "A", city: "Nashville", state: "Tennessee", zip: "37206", …}
taken: true
__typename: "Job"
_id: "6107fce77f7afc40e4e185a7"
[[Prototype]]: Object
length: 1
[[Prototype]]: Array(0)
Profile.js:32
Object
Profile.js:41
Last log from same line:
0:
category: "Yard Waste"
completed: false
createdAt: "Aug 2nd, 2021 at 9:10 am"
date: "2021-08-17"
description: "addas"
distance: "1.585"
driverEmail: "wfh2d88#gmail.com"
dropoff: {address: "1800 Stratford Ave", address2: "A", city: "Nashville", state: "Alabama", zip: "37206", …}
email: "wfh2d88#gmail.com"
id: "47"
phone: "6153050246"
pickup: {address: "207 Porter Village Circle", address2: "A", city: "Nashville", state: "Tennessee", zip: "37206", …}
taken: true
__typename: "Job"
_id: "6107fce77f7afc40e4e185a7"

Swift 5 group and split array of objects based on object value

I have a sorted array
let things = [
Thing(activity: "1", name: "value1"),
Thing(activity: "1", name: "value2"),
Thing(activity: "1", name: "value3"),
Thing(activity: "2", name: "value4"),
Thing(activity: "2", name: "value5"),
Thing(activity: "3", name: "value6"),
Thing(activity: "3", name: "value7"),
Thing(activity: "1", name: "value8"),
Thing(activity: "1", name: "value9"),
Thing(activity: "1", name: "value10")
]
I would like to produce array of arrays splitted when the activity value changes similar to the following
[[Thing(activity: "1", name: "value1"),
Thing(activity: "1", name: "value2"),
Thing(activity: "1", name: "value3")],
[Thing(activity: "2", name: "value4"),
Thing(activity: "2", name: "value5")],
[Thing(activity: "3", name: "value6"),
Thing(activity: "3", name: "value7")],
[Thing(activity: "1", name: "value8"),
Thing(activity: "1", name: "value9"),
Thing(activity: "1", name: "value10")]]
A generalized solution would be:
extension Sequence {
func grouped<T: Equatable>(by block: (Element) throws -> T) rethrows -> [[Element]] {
return try reduce(into: []) { result, element in
if let lastElement = result.last?.last, try block(lastElement) == block(element) {
result[result.index(before: result.endIndex)].append(element)
} else {
result.append([element])
}
}
}
}
Then you can do:
let results = things.grouped { $0.activity }
A less elegant (but slightly more efficient) solution would be:
extension Sequence {
func grouped<T: Equatable>(by block: (Element) throws -> T) rethrows -> [[Element]] {
var results: [[Element]] = []
var lastValue: T?
var index = results.endIndex
for element in self {
let value = try block(element)
if let lastValue = lastValue, lastValue == value {
results[index].append(element)
} else {
results.append([element])
index = results.index(before: results.endIndex)
lastValue = value
}
}
return results
}
}
As already mentioned by #matt in comments you can use collection method reduce(into:) to group your elements by checking if the activity of the last element of the last array is equal to the current element activity, if so just append a new element to the last array, otherwise append a new array with a single element to the outer array:
struct Thing {
let activity, name: String
}
let things: [Thing] = [
.init(activity: "1", name: "value1"),
.init(activity: "1", name: "value2"),
.init(activity: "1", name: "value3"),
.init(activity: "2", name: "value4"),
.init(activity: "2", name: "value5"),
.init(activity: "3", name: "value6"),
.init(activity: "3", name: "value7"),
.init(activity: "1", name: "value8"),
.init(activity: "1", name: "value9"),
.init(activity: "1", name: "value10")]
let grouped: [[Thing]] = things.reduce(into: []) {
$0.last?.last?.activity == $1.activity ?
$0[$0.index(before: $0.endIndex)].append($1) :
$0.append([$1])
}
print(grouped) // "[[__lldb_expr_1.Thing(activity: "1", name: "value1"), __lldb_expr_1.Thing(activity: "1", name: "value2"), __lldb_expr_1.Thing(activity: "1", name: "value3")], [__lldb_expr_1.Thing(activity: "2", name: "value4"), __lldb_expr_1.Thing(activity: "2", name: "value5")], [__lldb_expr_1.Thing(activity: "3", name: "value6"), __lldb_expr_1.Thing(activity: "3", name: "value7")], [__lldb_expr_1.Thing(activity: "1", name: "value8"), __lldb_expr_1.Thing(activity: "1", name: "value9"), __lldb_expr_1.Thing(activity: "1", name: "value10")]]\n"

How to update multiple objects in a single collection of mongodb?

I have one collection in mongodb as given below -
[
{
id: "1",
itemName: "pen",
quantity: 10
},
{
id: "2",
itemName: "notebook",
quantity: 20
},
{
id: "3",
itemName: "book",
quantity: 30
}
]
I have to update this collection in one go. From UI I am getting the request array as -
[
{
"id": "1",
"quantity": 12
},
{
"id":"2",
"quantity": 13
}
]
I need to update the corresponding objects. I can run it in a for loop and using
db.collection.update()
I can update it. But is there any way to pass the whole array to update the corresponding objects in one go?

Resources