Calling push() on array, TypeError: Attempted to assign to readonly property - reactjs

Working in React Native. I'm trying to declare an array and then push things to said array, but I'm getting the error TypeError: Attempted to assign to readonly property
CONTEXT:
The app prints via a thermal printer.
The print method receives an array of commands
Example:
print([{appendText: "blah"}, {
appendCutPaper: StarPRNT.CutPaperAction.PartialCutWithFeed,
}]
The print method is asynchronous and if you attempt to call the method again before the last call has finished, it errors.
Because of #2, we created a queue system that accepts a job (array of commands) and then works through the jobs synchronously.
In a React component, I'm attempting to create a job by declaring an empty array named printJob
and then pushing various commands to it. In this case, we take a snapshot of a View and then push the commands returned by the printImage method to the printJob array.
onClick={() => {
const printJob = []
viewShot.current
.capture()
.then((uri) => {
printJob.push(...printImage(uri))
})
.catch((err) => alert(err))
newPrintJob(printJob)
}
printImage returns the array of commands to print an image and cut the paper:
const CUT_PAPER = {
appendCutPaper: StarPRNT.CutPaperAction.PartialCutWithFeed,
}
export function printImage(uri) {
return [{ appendBitmap: uri }, CUT_PAPER]
}
So the goal is to generate the array of commands and pass that to the queue as a job. Now, I could just do newPrintJob(printImage(uri)) in the above case, which works completely fine. However, there is a particular setting the user can configure where it will need to print multiple images, one per ticket (in other words, multiple printImages). I want to consider all of that one job, hence the need to create the printJob array.
THE PROBLEM:
I'm getting an error TypeError: Attempted to assign to readonly property which seems to be triggered by printJob.push(...printImage(uri)). If I comment that line out, the error doesn't get thrown.
I don't understand why this would happen because you can call push on an array, even if it's declared as a constant. I also tried declaring it with var and let and still received the same error.
I hope I've provided enough context here. LMK if I need to add more.
Additional info:
"react": "16.13.1"
"react-native": "~0.63.3"

Turns out the issue was not pushing to the array. The issue was was trying to add the job to the queue:
newPrintJob(printJob)
...outside of the async's callback. Solution was to move the newPrintJob line into the .then block.

Related

How do I bulk/chunk paginate existing Seq[(String)] session value in Gatling?

I am executing a call that saves a lot of values into a Seq[(String)], it looks as follows:
.exec(session => {session.set("Ids", session("externalIds").as[Seq[String]])})
There is a reason why I have to create another session variable called Ids our of externalIds but I wont get into it now.
I than have to execute another call and paginate 10 values out of ${Ids} until I send them all.
(So in case of 100 values, I'll have to execute this call 10 times)
The JSON looks as follows:
..."Ids": [
"962950",
"962955",
"962959",
"962966",
"962971",
"962974",
"962978",
"962983",
"962988",
"962991"
],...
What I usually do when I have to iterate through one value each time is simply:
.foreach("${Ids}", "id") {
exec(getSomething)
}
But since I need to send a [...] Of 10 values each, I am not sure if it should even be in the scenario level. Help! :)
Use transform in your check to transform your Seq[String] into chunks, eg with Seq#grouped.
I couldn't figure out how to go about this within the session so I took it
outside to a function and here is the solution:
.exec(session => {session.set("idSeqList", convertFileIdSeqToFileIdSeqList(session("idsSeq").as[Seq[String]]))})
def convertFileIdSeqToFileIdSeqList(idSeq: Seq[String]): Seq[Seq[String]] = {
idSeq.grouped(10).toList
}
Note that when placing your list within a JSON body, you will need to use .jsonStringify() to format it correctly in the JSON context like so:
"ids": ${ids.jsonStringify()},

Why is my object not changing when I reassign properties in a forEach loop?

I am fetching an array of objects from an RX/JS call from an http backend. It returns an object which I am then trying to work with. I am making changes to this object using a for loop (in this example I am trying the .forEach because I have tried a number of different things and none of them seem to work.
When I run the code, I get a very weird problem. If I return the values of the properties, I get the new values (i.e. correctionQueued returns as true, etc.) but in the very next line, when I return the object, those same values are the same as the original (correctionQueued === false, etc.) HOWEVER, correctionStatus (which does not exist on the original object from http) sets just fine.
I don't understand how
array[index].correctionQueued can return true, but
array[index] returns an object with correctionQueued as false.
After the loop, the original array (checklistCopy) is identical to the object before the forEach loop, except the new property (correctionStatus) is now set, but all properties that I changed that were part of the original object remain as they were.
I have tried using a for of, for in, and .forEach. I have used the index to alter the original array, always the same result. Preexisting properties do not change, new properties are added. I have even tried working on a copy of the object in case there is something special about the object returned from rxjs, but to no avail.
checklistCopy.forEach((checklistItem, index, array) => {
if (checklistItem.crCode.isirName === correctionSetItem) {
array[index].correctionQueued = true;
array[index].correctionValue = mostRecentCorrection.correctionValue;
array[index].correctionStatus = mostRecentCorrection.status;
console.log(array[index].correctionQueued, array[index].correctionValue, array[index].correctionStatus);
console.log(array[index]);
}
}
);
I don't get an error, but I get..
Original object is:
correctionQueued: false;
correctionValue: JAAMES;
--
console.log(array[index].correctionQueued, array[index].correctionValue, array[index].correctionStatus);
true JAMES SENT
but when I print the whole object:
console.log(array[index]);
correctionQueued: false;
correctionValue: JAAMES;
correctionStatus: "SENT'; <-- This is set correctly but does not exist on original object.
console.log(array[index]) (at least in Chrome) just adds the object reference to the console. The values do not resolve until you expand it, so your console log statement is not actually capturing the values at that moment in time.
Change your console statement to: console.log(JSON.stringify(array[index])) and you should discover that the values are correct at the time the log statement runs.
The behavior you are seeing suggests that something is coming along later and changing the object properties back to the original value. Unless you show a more complete example, we can't help you find the culprit. But hopefully this answers the question about why your logs show what they show.
Your output doesn't make sense to me either but cleaning up your code may help you. Try this:
checklistCopy.forEach(checklistItem => {
checklistItem.correctionQueued = checklistItem.crCode.isirName === correctionSetItem;
if (checklistItem.correctionQueued) {
checklistItem.correctionValue = mostRecentCorrection.correctionValue;
checklistItem.correctionStatus = mostRecentCorrection.status;
console.log('checklistItem', checklistItem)
}
}
);

Drupal 7 hook_node_access not allowing "deny"?

I created a simple module:
function hook_node_access($node, $op, $account)
{
return NODE_ACCESS_DENY;
}
It does block the access to the node, but I get this error when visiting that page:
Notice: Trying to get property of non-object in node_node_access() (line 3089 of \www\modules\node\node.module).
This line reads:
3088. function node_node_access($node, $op, $account) {
3089. $type = is_string($node) ? $node : $node->type;
So basically, when I do this, $node is NOT a string, but also doesn't have a "type" value. I can only imagine that $node is a blank object when it hits this part of the code. But why?
UPDATE
I did a var_dump of the "node" object and I believe this is the contents:
int(436)
So, somehow the node id is getting pushed into this function, but not the node, AND the is_string function is not picking up that it's a string (because it isn't, it's an INT).
Any ideas?
UPDATE 2:
What makes all of these really bad for me, is that even though I'm logged into Drupal as a user that does not have access to these nodes, they still see them if they go to /node and scroll through the pages.
Am I missing something, because surely hook_node_access should block the nodes from being seen at /node ?
When implementing Drupal hooks, you should always replace 'hook' with your custom module name. For example:
function mymodule_node_access($node, $op, $account)
{
return NODE_ACCESS_DENY;
}
Also, you will need to clear out the Drupal cache each time you implement a new hook by going to admin/config/development/performance

Transfer file to webworker: DataCloneError: The object could not be cloned

I want to transfer a file from a form to a webworker. In chrome i simple can use this code to transfer a FileList-Object:
worker.postMessage(files: array_files);
But with Firefox i get this error:
Transfer file to webworker: DataCloneError: The object could not be cloned.
So i tried to use the Syntax for transferable objects. Something like this?
var post = {files: array_files, file_ids: response.file_ids};
worker.postMessage(post, [post]);
But with that i get this in Chrome
Uncaught DataCloneError: Failed to execute 'postMessage' on 'Worker': Value at index 0 does not have a transferable type.
And still
DataCloneError: The object could not be cloned.
in Firefox.
What is the right way to pass a FileList to a worker?
I don't know how to pass File objects with postMessage, but at the least I can advise that transferable objects do not work in this way. The optional second parameter is an array of the backing ArrayBuffer instances of any typed arrays you wish to pass. So for instance, suppose the message you would like to post is a structured object:
var message = {foo: 'abc', bar: new Uint8Array(...)};
worker.postMessage(message, [message.bar.buffer])
Also notice that passing a typed array to another worker/window as a transferable object makes the transferred array inaccessible from the sending worker/window.

Perl -- DBI selectall_arrayref when querying getting Not Hash Reference

I am very new to perl (but from a c# background) and I am trying to move some scripts to a windows box.
Due to some modules not working easily with windows I have changed the way it connects to the DB.
I have an sqlserver DB and I had a loop reading each row in a table, and then within this loop another query was sent to select different info.
I was the error where two statements can't be executed at once within the same connection.
As my connection object is global I couldn't see an easy way round this, so decided to store the first set of data in an array using:
my $query = shift;
my $aryref = $dbh->selectall_arrayref($query) || die "Could not select to array\n";
return($aryref);
(this is in a module file that is called)
I then do a foreach loop (where #$s_study is the $aryref returned above)
foreach my $r_study ( #$s_study ) {
~~~
my $surveyId=$r_study->{surveyid}; <-------error this line
~~~~
};
When I run this I get an error "Not a hash reference". I don't understand?!
Can anyone help!
Bex
You need to provide the { Slice => {} } parameter to selectall_arrayref if you want each row to be stored as a hash:
my $aryref = $dbh->selectall_arrayref($query, { Slice => {} });
By default, it returns a reference to an array containing a reference to an array for each row of data fetched.
$r_study->{surveyid} is a hashref
$r_study->[0] is an arrayref
this is your error.
You should use the second one
If you have a problem with a method, then a good first step is to read the documentation for that method. Here's a link to the documentation for selectall_arrayref. It says:
This utility method combines
"prepare", "execute" and
"fetchall_arrayref" into a single
call. It returns a reference to an
array containing a reference to an
array (or hash, see below) for each
row of data fetched.
So the default behaviour is to return a reference to an array which contains an array reference for each row. That explains your error. You're getting an array reference and you're trying to treat it as a hash reference. I'm not sure that the error could be much clearer.
There is, however, that interesting bit where it says "or hash, see below". Reading on, we find:
You may often want to fetch an array
of rows where each row is stored as a
hash. That can be done simple using:
my $emps = $dbh->selectall_arrayref(
"SELECT ename FROM emp ORDER BY ename",
{ Slice => {} }
);
foreach my $emp ( #$emps ) {
print "Employee: $emp->{ename}\n";
}
So you have two options. Either switch your code to use an array ref rather than a hash ref. Or add the "{ Slice => {} }" option to the call, which will return a hash ref.
The documentation is clear. It's well worth reading it.
When you encounter something like "Not a hash reference" or "Not an array reference" or similar you can always take Data::Dumper to just dump out your variable and you will quickly see what data you are dealing with: arrays of arrayrefs, hashes of something etc.
And concerning reading the data, this { Slice => {} } is most valuable addition.

Resources