Reputation: 1817
I have following code to select multiple contacts and the filter only names that have XYZ. I am using then and done to accomplish this filter. In my contacts, there is one contact named XYZ Dude and I am selecting it also. Shouldn't this contact be passed in my done method after the filtering logic I apply in the then method? Any ideas what I may be doing wrong here
var picker = new Windows.ApplicationModel.Contacts.ContactPicker();
// Open the picker for the user to select a contact.
picker.pickMultipleContactsAsync().then(function (contacts) {
var contactsStartingWithPrefixPa = contacts.filter(function filterContacts(contact) {
if (contact.name.match(/XYZ/))
return true;
return false;
});
}).done(function (contacts) {
// code never reaches here
if (contacts != null ) {
contacts.forEach(function (contact) {
if (contact !== null) {
// logic to use this contact
}
}
)}
});
Upvotes: 0
Views: 353
Reputation: 18078
Unless there's a good reason to separate the filter from the "logic to use this contact", then both can be performed in one looping operation.
var picker = new Windows.ApplicationModel.Contacts.ContactPicker();
// Open the picker for the user to select a contact.
picker.pickMultipleContactsAsync().done(function(contacts) {
if(contacts) {
contacts.forEach(function(contact) {
if(contact.name.match(/XYZ/)) {
// logic to use this contact
}
});
}
});
Otherwise, you're looping through contacts
with .filter()
then looping again with .forEach()
.
If you really must separate two aspects, then (assuming contacts
has a .filter()
method) you should be able to do so as follows :
var picker = new Windows.ApplicationModel.Contacts.ContactPicker();
// Open the picker for the user to select a contact.
picker.pickMultipleContactsAsync().then(function(contacts) {
return contacts ? contacts.filter(function(contact) {
return !!contact.name.match(/XYZ/);
}) : [];
}).done(function(contacts) {
contacts.forEach(function(contact) {
// logic to use this contact
});
});
Upvotes: 1
Reputation: 7024
The return value from contacts.filter is not a promise, so you don't need to do any additional chaining here. Your code should look like this, as contactsStartingWithPrefixPa is simply a projection of contacts, so you can just do a forEach iteration directly:
picker.pickMultipleContactsAsync().done(function (contacts) {
var contactsStartingWithPrefixPa = contacts.filter(function filterContacts(contact) {
if (contact.name.match(/XYZ/))
return true;
return false;
})
if (contactsStartingWithPrefixPa.length > 0) {
contactsStartingWithPrefixPa.forEach(function (contact) {
//Process
});
}
});
Chaining of promises only works when each step of the chain (except the last) returns a new promise. If there isn't a promise to return, you don't have another async step so you can just process what you need right ther
Upvotes: 0
Reputation: 5535
return contactsStartingWithPrefixPa
is required in the then function.
// Open the picker for the user to select a contact.
picker.pickMultipleContactsAsync().then(function (contacts) {
var contactsStartingWithPrefixPa = contacts.filter(function filterContacts(contact) {
if (contact.name.match(/XYZ/))
return true;
return false;
return contactsStartingWithPrefixPa;
});
Upvotes: 3