Dojo : Array is defined at top of file but is undefined - arrays

I have the prerequisite setup...
define([ "dojo/_base/array", array ...
I create my array "concats" in the "return declare([], { concats: [], ..." area. There is a method/function called _createForm: function (fields) { ...}
Inside of this function I have : this.concats = [];
Inside of _createForm is a call to another method/function called : _createFormElement and inside of there whenever I try to PUSH to this.concats I get
"TypeError: Cannot read property 'push' of undefined"
I've tried every conceivable method to add items to this array but nothing I do, short of including this.concats = [] in the _createFormElement function will let me. AND if I include this.concats = [] in the _createFormElement function then it erases the array...
So sure, it holds ONE object, but I need it to collect objects for each Form Field in a global-ish array.
I'm so confused.

So it turns out I just have to reference the "global" (but not really global) array variable like so in my _createFormElement function/method...
var myVariable = this.concats;
Then in that function I can push like so...
myVariable.push(itemToPush);

Related

angular extract field of an array of object

I don't understand something and need explanations please !
I have a datatable and selection of lines generate in my .ts an array of Operation object. here is my object class :
export class Operation {
id: number;
name: string;
}
this is the declaration of array :
selectedOperations: Operation[];
when I log in console before extraction of ids, I have this :
this.selectedOperations = {"selected":[{"id":1,"name":"My name 1"},{"id":3,"name":"My name 3"}]}
and when I want to extract ids with this :
let ids = this.selectedOperations.map(o => o.id);
I have an exception =>
this.selectedOperations.map is not a function
It's not the first time I have this problem and I'd like to understand why. I search some reasons and found differences between Array and object[] ? I think it's not really an array because there is the {"selected": before the array...
Can someone tell me the thing and help me for extract ids ?
thanks a lot !
{"selected":[{"id":1,"name":"My name 1"},{"id":3,"name":"My name 3"}]} => this is of type object, whereas your array declaration looks like this selectedOperations: Operation[];
You either directly assign the array to your variable:
this.selectedOperations = [{"id":1,"name":"My name 1"},{"id":3,"name":"My name 3"}];
Or you can change your variable type to any or object:
selectedOperations: any;
this.selectedOperations = {"selected":[{"id":1,"name":"My name 1"},{"id":3,"name":"My name 3"}]}
const ids = this.selectedOperations.selected.map(o => o.id);
this.selectedOperations.map is not a function error is caused by the initialization, map function is reserved for arrays, therefore it throws an error when you try to use it on an object type variable.
I would recommend the first approach by the way, declaring a variable as any or object is contradicting with the purpose of Typescript.
You need to make some improvements to the code. In order to get the ids, you need to add selected to this.selectedOperations. See below.
let ids = this.selectedOperations.selected.map(o => o.id);

What is purpose of the single colon in setState Array

Following proper standards of keeping this.state immutable
const name = this.refs.name.value;
const names = [ ...this.state.names, name ];
//add new name to names array, and finally
this.setState({ names: names });
So I'm trying to understand what is setState trying to do here. Replace the old names array with the new updated names array?
Well { names: names } is just plain simple javascript object and what setState does is that the state names is being mutated to the new state which is the updated array.
What you are seeing there is the spread operator .... In ruby we have something very similar called splat operator. names becomes the result of concatenating all the elements of this.state.names and name into a new array. setState({names: names}) then updates the internal state of the component with the new names property.
One of its uses it's spreading array to use it's elements as separate arguments for a function call.
// Equivalent
console.log(...[1,2,3])
console.log(1,2,3)
// Usage in function definition
function asdf(qwer, ...uiop) {
console.log('NICE', qwer, uiop)
}
asdf(1,2,3,4);
// a declarative replacement for this procedural code
function asdf2() {
var qwer = arguments[0];
var uiop = Array.prototype.slice.call(arguments, 1, arguments.size);
console.log('UGLY', qwer, uiop);
}
asdf2(1,2,3,4)
Beware JSX is a syxntax extension and may not have all the latest es5 and es6 features.
I guess the answer is there.
The single colon in array sets the array value to the object.
facebook.github.io/react/docs/react-component.html#setstate

TextField as variable on app launch sticked into LocalNotification

On second time I tap button I do not have value anymore. How to Load variable on every app load. The variable I am talking about is changing since it is always textField.text! and it is user input. I use it when user taps LocalNotification action, app opens and then function triggers like this:
NSNotificationCenter.defaultCenter().addObserver(self, selector: "someFunctionWhereIsMyProblematicVariableINeedToLoad:", name: IDENTIFIER, object: nil)
How to stick the variable every time user enters it, into local notification. Are every notification somehow different or just text changes?Are there any ID-s to make every notification special?
LocalNotificationHelper.sharedInstance().scheduleNotificationWithKey("someText", title: "see options(left)", message:textField.text!+"someText", date: deadlinePicker.date, userInfo: userInfo)
I need that textField.text to be in this variable: let predicate = CNContact.predicateForContactsMatchingName(textField.text!)
I tried to store them into NSUserDefaults and into arrays and loop through arrays to find if value exists etc. But It works only first time and second time it is nil
Edit: It keeps only the last entered value as variable. How to keep them all?
Here I show you in the pictures what I tried to explain with words:
Now if blue button is tapped I start function where I need to use the "firstTimeEntered" as variable but at the second notification it is"SecondTimeEntered"
Variables class scope:
var sentence:String = ""
var firstWord = [String]()
var firstWordAsString:String = ""
Function "A":
sentence = textField.text! + " needs to be deleted from array."
var firstWordAsString = sentence.characters.split(" ").first.map(String.init)
firstWord.append(firstWordAsString!)
defaults.setObject(firstWord, forKey: "firstWord")
let userInfo = ["url" : "Hello"]
//Set notification
LocalNotificationHelper.sharedInstance().scheduleNotificationWithKey("someText", title: "see options(left)", message: sentence, date: deadlinePicker.date, userInfo: userInfo)
Function "B":
defaults.objectForKey("firstWord") as? String
if contacts.contains(firstWordAsString){
let predicate = CNContact.predicateForContactsMatchingName(firstWordAsString)
This is ultimately an issue of scope.
//This is the largest scope called the global scope. anything available here is available anywhere in your application.
class myclass {
//this is the class level scope any variables here would be available from within the class but not outside of it. I can use any variables in the class scope or the global scope.
func myFunction() {
//this is the function scope, any variables here would be available from within the function but not outside of this function. I can use any variables in the class scope, global scope and my own scope.
}
func mySecondFunction() {
//this is also the function scope, I can have my own variables but I cannot see the variables in myFunction()
}
So if you were to put a var savedValues = [String]() at the top of a function it would not be available from another function. but if you put the same in the class scope, it would be available in both functions. Each time a function starts, it will define the function variables and when it exits itself, the variables are removed from memory.
to solve your issue put an array of strings within your class, and then use the append method of that class level array to add new things to it. you could then search against that array by using the filter method or looping though it.

angular - fail to update array from service

I got a service that contain some contacts (name,phone). The controller has array that contain a reference to the array from the service so for every change on the array all gets updated.
Service:
app.service('ContactManagerService', function()
{
this.Contacts=[];
...
this.AddContact=function(Contact){...};
this.RemoveContact=function(Contact){...};
...
});
First question: Is this a good approach? Should every controller/directive need to have a direct reference to the original array from the service? I have read a lot about setting up some events from the service to the controllers when the array has been changed, but it sound stupid because the array on the controller will be change anyway (because its the same array) and the ng-repeat will be updated automatically.
Second problem: The service has a method that replace the array to new one:
this.ReplaceContacts=function(NewContacts)
{
this.Contacts=NewContacts;
});
The ng-repeat does not update because the controller still got the old reference to the old array. So a refresh need to be done.
I tried to replace the code to this one so the same array's reference wont change, but when the the code enter the foreach, this.Contacts array is undefined and the code stops. Why ?!
this.ReplaceContacts=function(NewContacts)
{
this.Contacts.splice(0, this.Contacts.length); //remove all contacts
NewContacts.forEach(function (contact, index)
{
this.Contacts.push(contact);//place the new ones
});
});
The controller code:
app.controller("myCtrl",
function ($scope,ContactManagerService)
{
$scope.Contacts = ContactManagerService.Contacts;
$scope.AddContact= function (Contact1) {
ContactManagerService.AddContact(Contact1);
}
$scope.RemoveContact = function (ContactID) {
ContactManagerService.RemoveContact(ContactID);
}
});
I hope everything is clear,
Thanks.
Because the callback function passed to forEach isn't bound to the service instance. So this, inside the callback, is not the service.
My advice: avoid this like the plague. It's an enormous source of bugs in JavaScript.
Use
var self = this;
at the top of the service, and use self instead of this everywhere.
Or bind the callback function to the service instance:
NewContacts.forEach(function (contact, index) {
...
}, this);
You can simply push elements to Contacts using Array.prototype.push()
The push() method adds one or more elements to the end of an array and returns the new length of the array.
this.ReplaceContacts=function(NewContacts){
this.Contacts.splice(0, this.Contacts.length); //remove all contacts
Array.prototype.push(this.Contacts, NewContacts);
});
As mentioned in previous anser, context of this in forEach loop is not what you think it is.
A simplification would be to use Array.prototype.concat():
var self = this;
self.ReplaceContacts = function (NewContacts) {
self.Contacts.splice(0, this.Contacts.length); //remove all contacts
self.Contacts.concat(NewContacts);
});

Symfony2 - Trouble using usort inside a controller

I am trying to merge the contents of 2 arrays then use usort to get the posts with most views.
Trying to use usort to sort the contents of an array.
Am getting the follow error:
("Notice: Undefined property: Acme\DemoBundle\Entity\Article::$getViews in /.../PageController.php line 15")
Can someone point out what I am doing wrong?
Sort function inside of controller
private static function popularSort($articles, $posts, $articles2, $posts2)
{
return $articles->getViews() == $posts->getViews() ? 0 : ( $articles->getViews() < $posts->getViews()) ? 1: -1;
}
Sidebar action
$articles = $this->getDoctrine()->getRepository('AcmeDemoBundle:Article')
->getArticles();
$posts = $this->getDoctrine()->getRepository('AcmeDemoBundle:Post')
->getPosts();
$popular = array_merge($articles, $posts);
usort($popular, array($this, 'popularSort'));
getViews is a getter method for accessing the property views of the Entities Post and Article. So while accessing it u should access it as $articles->getViews().
But if you simply want to compare the property views of the two entities compare them using their property name instead of their getter
Assuming views as the name of the property, the call should be something like:
$posts->views and $articles->views.
You don't have a property called getViews in your Article class.
You probably have a property called views and a method getViews meaning you should call the actual method with the brackets like $article->getViews().

Resources