Angular/Ionic HTTP response data different from server - javascript

I've hit a snag and I'm hoping you guys can help:
I have a basic HTTP get in Angular - I've done it 100 times at this point. My JSON response on the server, confirmed, is formed like so:
[{"date":"07\/24\/2017","time_start":"02:00 PM","time_end":"05:00 PM","name":"Adult Ministries Registration","room":"","speaker":"none","speaker_writein":"","xhead":"yes"}]
You see the final property is "xhead" and it's a string "yes" or "no" - which I'm using to determine when to show titles that break up events by day (grouping them by time under a date in a schedule list).
The problem for me is that when this data comes into the Angular app, "xhead" is undefined. I'm doing a simple console.log on the response data and it shows as undefined.
Even more odd is that if I change these values to 1 or 0, they all come into Angular as either 1 or 0 - not differentiated as they should be for each item in the collection (response).
When i visit the endpoints in the browser, the data is as it should be.
Help!!! I'm losing my mind.

It appears as though using ng-if="response.xhead=yes" in the view changes the value of the item. That was the problem.
The ngIf directive removes or recreates a portion of the DOM tree based on an {expression}. If the expression assigned to ngIf evaluates to a false value then the element is removed from the DOM, otherwise a clone of the element is reinserted into the DOM.

Related

Why after the changes the list is not displayed and the functional that I need does not work? How to fix it?

I have an object in which the array is located, and using the fetch method I get a data object and then I have a list of factory workers + a filter on the page.
Here is my application code:
https://codesandbox.io/s/sad-bas-ej8l5
But I had to add two buttons, when the first button is pressed, the list of employees which go to the first shift is displayed, and when the second button is pressed, the employees which go to the second shift.
What I added to the code:
1) in the file today.json added the object second (the list of employees of the second shift)
2) added the SecondToday.js file and created the SecondToday component (to display the second shift list)
3) in App.js in state added the defaultTab property with true value and then created two methods that change the state and, depending on this, in the render method, display the FirstToday component (list of first shift workers) or the SecondToday component(list of second shift workers).
But after my changes now the list is not displayed at all ....
Here's a new option:
https://codesandbox.io/s/focused-ellis-wbkyr
How to fix the problem? What have I not done?
Your issue is related to the fact that your .json data file is not correctly formatted as json.
I replaced your json data file with the working one and it now loads correctly.
The 2nd problem of it still not displaying after that is fixed has to do with your data verification check in SecondToday.js. You are checking to see if props.data.group.second exists, but it's undefined. If you log your props, it shows that your second key exists outside of group.

What could cause iterating over an array in Meteor template to produce an extra value?

I have the following code in a Meteor Blaze template:
<template name="showCalled">
{{called}}
<br>
{{#each called}}
{{this}},
{{/each}}
</template>
Called is a property of the data context where this template is used. I am then getting the following results when the page renders:
4,2,6,2,0,0,0
4, 0, 2, 6, 2, 0, 0,
Note the extra element in the second location and the final element being dropped. The initial list produced by the {{called}} is the correct one. I'm completely stumped as to what could cause this behavior.
If I refresh the page, it works fine - I only get this behavior when the template updates reactively.
The difference is always an extra element in the second place, though it's not always 0. It is deterministic (as far as I can tell) and seems to be related to what was there before. Specifically the value entered in that second place seems to be the value that was in the second place of the correct array prior to the update.
Is this just a Meteor bug or is there something I could be doing to cause it?
UPDATE: I get this behavior even if I manually set the value of called to a static array in the helper function, though then it inserts the extra value in the 5th place.

ArrayCollection (Collection of forms) index collision in Symfony 2

I am using Symfony2 to build up my page.
When I try to update a collection of forms (like described in the cookbook entry "How to Embed a Collection of Forms"), i get a collision of the indexes of the frontend and the indexes of the ArrayCollection in the backend.
I've got the relation User <-> Address (OneToMany). A user wants to create/update/delete his addresses, therefore he can add / delete in the frontend with the help of the javascript part new address elements. He does the following:
(1) Adds new address (has index: 0)
(2) Adds new address (has index: 1) and instantly removes this address again
(3) Adds new address (has index: 2).
When he clicks on save button, the following code saves/updates the user (and its addresses):
$this->em->persist($user);
$this->em->flush();
New addresses for example are then correctly persisted to the database.
Now the user wants to update the address e.g. with index 0.
When he now clicks on the save button, it updates the adress with "index 0", but at the same time, it adds again the address with "index 2" to the database (object).
To better understand the problem, i've drawn a small illustration (handmade, sorry for my bad art skills):
Now , i've got two times the address with "index 1" within my object / database.
I know why this happens, it's because the first "index 1" address gets mapped to the ArrayCollection element "number 1", and the second gets mapped to "number 2 "(because of the frontend name "index 2").
You can say: "it just fills up the addresses, until it reaches the frontend index in the backend"..
But how can I fix this behaviour ?
Site note:
This behaviour occurs using ajax requests, because if you would reload the page after clicking "save button", it would reindex the addresses in the frontend correctly with the indexes in the backend.
My suggestion to handle that situation:
Reindexing the frontend indexes after clicking save with the server side
indexes. Is this a clear / the only solution for my problem?
Yes, this is problem of Symfony form collection and it has no easy solution imho. But I have to ask why don't you do exactly the same thing what page refresh does? You can refresh only html snippet with collection. HTML code for snippet can come from server-side. Back to your question - yes, reindexing is good solution until you do not want to try write custom collection type on your own.
symfony/symfony/issues/7828
There is similar problem with validating in collection - symfony/symfony/issues/7468.
Well I think default collection type and the tutorial in Symfony docs has the some drawbacks. Hope that's help.
I have come round this issue on the client side by modifying the Javascript/Jquery code given in the Symfony Documentation.
Instead of numbering the new elements by counting the sub-elements, I am looking at the last element's id and extracting its index with a regular expression.
When adding an element, I am incrementing the last index by 1. That way, I never use the same index.
Here is my code :
// Initializing default index at 0
var index = 0;
// Looking for collection fields in the form
var $findinput = $container.find(':input');
// If fields found then looking for last existing index
if ( $findinput.length > 0 ) {
// Reading id of last field
var myString = $findinput.last().attr('id')
// Setting regular expression to extract number from id containing letters, hyphens and underscores
var myRegex = /^[-_A-Za-z]+([0-9]+)[-_A-Za-z]*$/
// Executing regular expression on last collection field id
var test = myRegex.exec(myString);
// Extracting last index and incrementing by 1
if (test.length > 0) index = parseInt(test[1]) + 1;
}
I ran into this problem a couple of times during the past two years. Usually, following the Symfony tutorial How to Embed a Collection of Forms does the job just fine. You need to do a little bit javascript coding to add the "edit/update" functionality, but other than that - you should be just fine using this approach.
If, on the other hand, you have a really complex form which uses AJAX to validate/save/calculation/business logic/etc, I've found it's usually a better to store the final data into an array in the session. After submitting the form, inside the if($form->isValid()){...} block, you would have
$collection = new ArrayCollection($mySessionPlainArray);
$user->setAddress($collection);
I would like to warn you to be careful with the serialization of your data - you might get some awkward exceptions or misbehavior if you're using entities (see my question).
I'm sorry I can't provide more code, but the solution to this problem sometimes is quite complex.

JavaScript items disappearing from Array

I have an array called objs that holds all of my application objects. Objects get added and removed from this list depending upon what happens in the application.
I am having this problem where some objects disappear (or are overwritten) only sometimes. If I step through the add and remove functions, the app always runs as it should, however many times when it is run without the debugger, one or two objects that were added to the end of the list disappear from the list.
objects are added to the array like this:
this.objs[this.objs.length]=obj;
and are removed from the array like this:
for(var i=0;i<this.objs.length;i++)
if(this.objs[i]==obj)
return this.objs.splice(i,1);
I put this code at the end of my add and remove functions:
console.log("add! ");
console.log(this.objs);
Linked is an image of a console log during a session where an object dissapeared: http://ilujin.com/error.png
The first 4 objects in the list shown at the top should remain in the list throughout the session, but the object at index 3 (highlighted in red), gets overwritten by the next object that gets added (highlighted in blue).
The other weird thing is that the second list shown already has all of the changes (4 objects removed and 1 added), even though the remove function has only been called once and the add function not at all.
This makes me conclude that the problem is timing - if one add hasn't finished before the next add is called, the first one will be overwritten. And all of the console prints are the same because they all happen before the console can read and print.
Does this makes sense? For some reason I thought JS never ran parallel code and only moved on to a new function when the last function finished. Is the problem that I'm using the length of the objs list as the new index when I add to the list?
How can I fix this issue? I can't figure it out, and the debugger and console have proven useless.
Here is the app: http://iioengine.com/neuro/study2.htm
you only need to enter an id and see if the instructions pop up. If they do, than its working and refresh. If they don't, that means that the Text Object got overwritten.
You would really be better served by using Javascript's array methods.
Add to array:
this.objs.push(obj);
Remove from array:
this.objs.splice(this.objs.indexOf(obj), 1);
Also, note that splice edits the original array and returns the elements that have been removed. It's hard to tell from your limited code sample, but that might also be causing issues.

Array displays length of 0 sometimes

I am having an extremely bizarre problem. I have a Backbone collection, and I am using the where method to find models in the collection that match a certain attribute. My problem is the inconsistency of the results.
I have a joinedGoalList which keeps track of goals that a user has joined. Let's say that this collection contains two goals with IDs of 1 and 3. When a user accesses /goals/3, a message should display saying that the user has joined the goal
I am having a problem where I am accessing /goals/3, and half the time the message displays, and the other half of the time, the message does not display.
The odd thing is that this problem only happens on my remote server and not on my local host.
In my code, I query the joinedGoalList for an ID of 3, and if it matches, I know that the matches array has to be greater than 0, so I render the message showing that the user has joined the goal.
Here is the code (joinedGoalList is a Backbone collection:
console.log(joinedGoalList);
var matches = joinedGoalList.where({id: this.model.get("id")});
console.log(matches);
console.log(matches.length);
if (matches.length > 0) {
console.log("the matches length is > 0");
this.renderLeaveGoal();
} else {
console.log("the matches length is 0");
this.renderJoinGoal();
}
Here are the results of console.log(joinedGoalList), here are the results(they are consistent):
child
_byCid: Object
_byId: Object
_callbacks: Object
length: 2
models: Array[2]
__proto__: ctor
As you can see, the length is 2. One of the objects has an ID of 1 and the other object has an ID of 3. This is consistent throughout the page loads.
The inconsistency occurs when I do a match on the array for an object with an ID of 3. Some page loads find the match while other page loads do not find the match.
The results of console.log(matches.length) are either 0 or 1 on my remote server, yet on my localhost, the results are always 1.
I'm pretty sure that the sequence of events goes like this:
You call fetch on the collection to load your data from the server.
You call console.log(joinedGoalList), this is asynchronous in some browsers.
You call joinedGoalList.where and find an empty collection.
The fetch call from 1 returns and populates the collection.
The console.log call from 2 executes and prints out the populated collection, this call will have a reference to joinedGoalList and that reference will now be pointing at a populated collection.
When you do this locally, the AJAX fetch in 4 returns quite quickly so step 4 occurs before 3 and everything behaves the way you'e expecting it to.
You have a couple options here:
fetch has a success callback:
The options hash takes success and error callbacks which will be passed (collection, response) as arguments.
So you could use the success callback to delay whatever is calling where until the server has responded and the collection is populated.
fetch resets the collection:
When the model data returns from the server, the collection will reset.
and reset will
replace a collection with a new list of models (or attribute hashes), triggering a single "reset" event at the end.
So you could listen for the "reset" event and use that event to trigger whatever is calling where.

Categories

Resources