|
NoMoreStackOverflow wrote: that a tested method does not make other calls than the monitored
Looking at that again and based on your other response....
No I doubt that exists. I have no idea how a test framework would even implement that. It would at a minimum require that the test code would have to specify every call that the code would make.
Only reasonable way I could even think that part would work is that every single method call would need to be mocked. Because otherwise a call to another class could then call to another method that was not tracked.
Additionally I suspect that maintaining it would be a maintenance nightmare.
A unit test should test that the method works. Not how the method implemented the solution.
|
|
|
|
|
Hello jschell,
THX a lot again for your reply and contribution
I have no idea about how to implement such a testing framework.
I just had that idea about "what if" and thats why I asked the question
Also a solution (if there is any) should be easy to implement and handle for me
So thanks again and maybe at some pt in the future I'll get a clue..
Best Regards
|
|
|
|
|
I wrote a function, where one can update an invoice. So the user clicks edit, the modal pops up, they change the price, and the function calls an API, updates the database, and processes the returned data.
Then it calls a function within, that changes the invoice price on the page, and creates a mutation observer to detect the price change, and tallies up the invoice cost, and changes the total at the bottom.
The purpose of this mutation observer, is to wait for the DOM to update the cost, and when the DOM signals it's been done, then go back to the DOM and tally up the cost, and change the total cost span element value.
Everything works, but it only works if you do this twice. Like if I edit using the modal, submit, the observer doesn't fire. but if I edit the invoice again, then it works.
Should I call my function within my function again?
Or am I missing something here, and need to redesign the whole thing.
I'm reluctant to post any code, because the function is huge, I'll post the basics here.
I'd hate to have to split code up here, but might have to. move the mutation observer outside the posted function, to inside the API function call.
I want to do this the correct way, so it doesn't come back on me and works every time.
Calling function
function callApi() {
Prepare to send data
fetch {
.then(data => {
process data
call the function below
}
}
The function called after fetch, I can target the entire invoice within the DIV, but I targeted the single span element that contains the cost.
export function updateAnyTypeInvoiceInvoiceRecordMutationObservable(classCode, catalogId, invRecordId, jsonData, data) {
Javascript that changes the invoice values
const observer = new MutationObserver(mutationsList => {
for (const mutation of mutationsList) {
console.log('Text content has changed:', mutation.target.textContent);
Code that adds up all the invoice cost, and changes the total at the bottom
let mutationRecords = observer.takeRecords();
console.log(mutationRecords);
observer.disconnect();
}
});
const config = { childList: true, subtree: true, characterData: true };
const targetNode = document.getElementById('invInvoiceAmount_' + classCode + '_' + invRecordId);<br />
observer.observe(targetNode, config);
Perhaps, call this function again here?
} catch (error) {
console.log('updateAnyTypeInvoiceInvoiceRecordMutationObservable Error', error);
alert('updateAnyTypeInvoiceInvoiceRecordMutationObservable Error: ' + error);
}
}
If it ain't broke don't fix it
Discover my world at jkirkerx.com
|
|
|
|
|
Strange how when I post something here, it makes me rethink the problem in a different way.
I concluded that I need to create the observer first, populate that observer with code to update the totals posted at the bottom, and then run the code to change the invoice. Pretty much backwards in order, but I get it now. At least I think this is correct, and it works so far, but I haven't tested enough to confirm that it doesn't conflict with anything.
Makes sense now, setup the mutation observer, program the response when it fires, then run the code to update the invoice.
export function updateAnyTypeInvoiceInvoiceRecordMutationObservable(classCode, catalogId, invRecordId, jsonData, data) {
const observer = new MutationObserver(mutationsList => {
for (const mutation of mutationsList) {
console.log('Text content has changed:', mutation.target.textContent);
Code that adds up all the invoice cost, and changes the total at the bottom
let mutationRecords = observer.takeRecords();
console.log(mutationRecords);
observer.disconnect();
}
});
const config = { childList: true, subtree: true, characterData: true };
const targetNode = document.getElementById('invInvoiceAmount_' + classCode + '_' + invRecordId);<br />
observer.observe(targetNode, config);
Javascript that changes the invoice values called last
} catch (error) {
console.log('updateAnyTypeInvoiceInvoiceRecordMutationObservable Error', error);
alert('updateAnyTypeInvoiceInvoiceRecordMutationObservable Error: ' + error);
}
}
If it ain't broke don't fix it
Discover my world at jkirkerx.com
|
|
|
|
|
jkirkerx wrote: I concluded that I need to create the observer first, populate that observer with code to update the totals posted at the bottom, and then run the code to change the invoice.
Correct - the mutation observer can't notify of mutations that occurred before you started observing them.
That leads to the question of why it seems to work the second time. Since the first observer is only disconnected once a mutation has been observed, it will still be waiting to observe a mutation when the second update is applied.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
It's my first time working with this, and it took me awhile to figure out how it works. That's for confirming my thought on this!
If it ain't broke don't fix it
Discover my world at jkirkerx.com
|
|
|
|
|
Tammy Gombez wrote: I'm currently facing a perplexing issue Do you mean why have you posted a C++ question in the Javascript forum?
|
|
|
|
|
More like "How do I get banned for spam as quickly as possible?"
Spammer in JavaScript forum (Tammy Gombez)[^]
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Still learning.
I'm using the SWAPI - The Star Wars API for my test data.
I can fetch the data from https://swapi.dev/api/people (no problem)
But I'd like to be able to iterate over the films array to fetch each movie name.
I'm not sure what the syntax I should use, or if it is the proper way to do it.
the getFilmName function returns
[object Promise]
I tried adding an await before the call to getFilmName and give does not "compile" :
const filmName = await getFilmName(filmURL);
Thanks.
async function getFilmName(url) {
const res = await fetch(url);
const data = await res.json();
return data.title;
}
async function getPeople() {
console.log("fetchNames");
const url = "<a href="https:
const res = await fetch(url);
const data = await res.json();
console.log(data);
const results = data.results;
results.map((person) => {
console.log(<code>${person.name} stars in :</code>);
person.films.map((filmURL) => {
console.log(filmURL);
const filmName = getFilmName(filmURL);
console.log(<code>filmName: ${filmName}</code>);
});
});
}
getPeople();
Thanks.
CI/CD = Continuous Impediment/Continuous Despair
|
|
|
|
|
Maximilien wrote: I tried adding an await before the call to getFilmName and give does not "compile" : The calling function would also have to be asynchronous or called within the context of a promise.
async function blah() {
try {
const response = await fetch('blah.com');
return await response.json();
} catch(ex) {
console.error(ex);
}
}
blah();
(async () => {
await blah();
})();
Jeremy Falcon
|
|
|
|
|
Thanks, but that does not help with my example.
My problem is with the getFilmName function (or the call to).
CI/CD = Continuous Impediment/Continuous Despair
|
|
|
|
|
Jeremy is correct - any function that uses await needs to be marked as async .
In this case, the callback to map would need to be async . However, that would result in an array of promises.
But since you're not doing anything with the array returned from either map call, that won't make much difference.
Assuming you actually want to do something with the results, try:
async function getPeople() {
console.log("fetchNames");
const url = "https://swapi.dev/api/people";
const res = await fetch(url);
const data = await res.json();
console.log(data);
const results = data.results;
const promises = results.map(async (person) => {
const filmPromises = person.films.map(getFilmName);
const films = await Promise.all(filmPromises);
return { person, films };
});
return await Promise.all(promises);
}
(async () => {
const people = await getPeople();
people.forEach(person => {
console.log(`${person.person.name} stars in :`);
person.films.forEach(filmName => console.log(filmName));
});
})(); Demo[^]
Promise.all() - JavaScript | MDN[^]
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Thanks,
I'll study this.
I'm not sure I still understand.
CI/CD = Continuous Impediment/Continuous Despair
|
|
|
|
|
I'll help you with the array of promises part, but not until I get a thumbs up too.
Jeremy Falcon
|
|
|
|
|
I promise I will.
CI/CD = Continuous Impediment/Continuous Despair
|
|
|
|
|
Richard is spot on with his reply. Mine was more theory. Take it as a compliment. Sometimes I just chat theory when I recognize the poster because I trust they take it and run with it. It's still the same principle, but just needs to be called from within the context of an Array.prototype.map callback. There are a couple ways to go about this.
1 You can still use an async IIFE anyway. IIFE is a functional/JavaScript concept that stands for Immediately-Invoked Function Expression and is pronounced iffy . It does exactly what it says and can be put anywhere. It's a quick and dirty way to call async code from a sync routine as well.
2 You can make the map callback itself async. However, this means you'd also have to deal with sync/async issue still.... just "one level" higher so to speak. Array.prototype.map iterates, much like IEnumerable in C#. In JavaScript, async/await is essentially syntax sugar for promises. Makes life easier and for cleaner code. But it also means you can interchange them and loop through your nested map like this:
results.map(async person => {
await Promise.all(arr.map(async filmURL => {
const filmName = await getFilmName(filmURL);
}));
};
Keep in mind though, this simply shifts the requirement for async up one nested level. The parent map would still have to be called within the context of a promise or async/await still. Same exact syntax. Keep in mind though, using Promise.all is old. It works, but no cool points for using it.
As a side note, this is mainly for educational purposes. An API shouldn't be called in a loop. Redesigning the API, using GraphQL, streaming the data, etc. should all be considerations to rethink the approach of opening web requests in a loop.
Buttttt.... if you need a loop-like concept, you'd be better off with generators. For example, if you used generators, you'd be able to pull off something like this. Just trying to whet your appetite.
for await (const filmName of getFilmNames()) {
}
Anywho, the super short answer is just go with #2 and don't forget to use promise.all on the outer nest too.
Jeremy Falcon
|
|
|
|
|
I'm trying to show progrees bar while uploading a file using axios, according to this youtube channel : OpenJavaScript("Axios upload progress with progress bar tutorial"). If I use 'https://httpbin.org/post' for the axios post parameter it run well, but if I change to my destination folder (D:\laragon-portable\www\cv\public\uploads) it result with error 'POST http://localhost:8080/uploads 404 (Not Found)', I tried 'http://localhost:8080' and 'http://localhost:8080/uploads'(I use local development server in CodeIgniter 4), but it error too,....what should I write for the url ?
|
|
|
|
|
(not sure where to ask this).
Still learning...not for work.
I have a valid json (geojson) file like this : (reduced for visibility, original : Murales subventionnées - Site web des données ouvertes de la Ville de Montréal )
it's a list of features but the id is in a sub field of the feature.
{
"features": [
{
"type": "Feature",
"properties": {
"id": 1,
"annee": "2007"
},
"geometry": { "type": "Point", "coordinates": [-73.622218, 45.58041] }
},
{
"type": "Feature",
"properties": {
"id": 2,
"annee": "2007"
},
"geometry": { "type": "Point", "coordinates": [-73.558029, 45.506855] }
}
]
}
I can fetch the whole list with the following and it works :
fetch ("http://localhost:4000/features );
I'm trying to use fetch to get a single "feature" from the file:
fetch ("http://localhost:4000/features/1");
But this does not work, it returns nothing.
I tried different format for the fetch URL.
If I move the id property to the root of each item, it works, but I don't want to do that.
Am I missing something ?
Is there anything I can do ?
Thanks.
CI/CD = Continuous Impediment/Continuous Despair
|
|
|
|
|
fetch sends a request to the server, and returns the response. It doesn't attempt to interpret the response and extract any part of it.
Unless you have a specific endpoint on the server to handle the request for a single feature, you'll need to fetch the full list and parse it yourself.
(async () => {
const response = await fetch("http://localhost:4000/features");
if (!response.ok) {
alert("Error loading the feature list.");
return;
}
const { features } = await response.json();
const specificFeature = features.find(f => f.properties.id === 1);
if (!specificFeature) {
alert("Feature 1 was not found.");
return;
}
})();
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
thanks,
I'll probably do it manually.
but I don't understand who/what creates those end points.
for example, if I have this simple json file:
{
"items": [{
"id": 1
},
{
"id": 2
},
{
"id": 2
}
]
}
I can fetch individual items with http://localhost:3000/items/1
but if I have :
{
"items": [{
"properties":{
"id": 1
}
},
{
"properties":{
"id": 2
}
},
{
"properties":{
"id": 3
}
}
]
}
it does not work.
CI/CD = Continuous Impediment/Continuous Despair
|
|
|
|
|
You need to look at the code that's running on your server. As far as I'm aware, there's no magic tool that would convert a URL like "/items/1" into a request to load a JSON file called "items", get the "items" property from the root object, find the entry with id === 1 , and return just that object. You must have code running which does that, which you (or someone else) has written.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
My colleague, who is on vacation, wrote a Javascript application that I need to port to C#. I know nothing about Javascript so at this point I'm happy if I'm just able to execute it successfully. There is a file called "index.html" and when I open this in Chrome I can see buttons, textboxes, comboboxes, etc but everything is "dead" , nothing happens when I e.g. click a button. Does anybody know how I can bring the application to life? Also, does anybody know if there exist a free IDE where I can edit the source code (it would be a bonus if I can step the code as well)?
Updated information: I installed "Visual Studio Code" and opened the project folder there and when I click "Start Debugging" I see the GUI flashing by quickly and then nothing happens. In the "Terminal" window I see the following:
"npm run start
Debugger attached.
> firmwareprogrammer@1.0.0 start
> electron .
Debugger attached.
Main process started
Waiting for the debugger to disconnect...
Waiting for the debugger to disconnect..."
Updated information again: I'm now able to step the code in "Visual Studio Code" and when the following function is executed, the GUI-windows are showing (but they are all white), but as soon as the function is finished executing the GUI-windows disappear:
function createWindow () {
mainWin = new BrowserWindow({
width: 1100,
height: 870,
minWidth: 1100,
maxWidth: 1100,
minHeight: 870,
maxHeight: 870,
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
enableRemoteModule: true,
}
})
devtools = new BrowserWindow();
mainWin.webContents.setDevToolsWebContents(devtools.webContents)
mainWin.webContents.openDevTools({ mode: 'detach' })
mainWin.loadURL(url.format({
pathname: path.join(__dirname, 'index.html'),
protocol: 'file',
slashes: true
}))
mainWin.webContents.openDevTools()
mainWin.on('close', () => {
mainWin = null;
})
}
modified 17-Mar-23 9:07am.
|
|
|
|
|
No idea where to start with this.
A javascript "application" is not the same as a "web server" which responds to requests and which might use javascript.
So at least from your description it is not clear that you know what it is.
If it is a web server then, of course, the first step is that you either must set up a web server or have something that will act as a container (proxy) to run it as though it was in a web server.
If it is an application instead then it has nothing to do with a browser.
A 'index.html' suggests a web application. Hard to say how you might run this but I know that can be used in IIS with the appropriate AppPool (and other stuff set up). Then IIS is the web server. With my very limited experience node.js might be set up in a similar way. There are other ways this can be setup.
Regardless though it likely requires additional steps besides just identifying the container.
------------------------------------------------------------------
Other than the above your company has a SEVERE problem with documentation. This is not something that you should be guessing about. What if your coworker just left the company (fired, quit, died) then what?
Production setups should ALWAYS be documented. Development setups should be documented in such a way that it does not require another developer working full time just to get a new developer up and running. Detail helps but it not required.
|
|
|
|
|
I'm studying Front-End Development and I try to Validate this form: https://rfh-js1.netlify.app/contact.html
The validation script is: https://rfh-js1.netlify.app/js/validation.js
I have tried to set 4 global variables (value = 0) first on validation.js, then Im doing the validation in 4 separate functions and set the variable to 1 if validation rules is succsessful and 0 if they fail.
Then after validation I sum the values of these global variables and set the submit-button to display if sum = 4 else display="none"
but logging the global variable in console.log only give me 0…
|
|
|
|
|
There are positive number which has no prime factor larger than 5
So the first few numbers are 1, 2, 3, 4, 5, 6, 8, 9, 10
Write a function which takes a positive number as input and returns true if it has no prime factor larger than 5
The return type should be a boolean.
isPrimeFactorLargerThanFive(10) Should return true
isPrimeFactorLargerThanFive(13) should return false
The answer should be valid for any given input.
|
|
|
|
|