function not return value from request - javascript

I made a function to get request. It look like this
export const toggleCompleted = (id) => {
axiosMethod.get('api/taks/toggle/' + id)
.then(res => {
console.log(res.data)
return res.data;
}).catch(error => {
return error;
})
return 'Test';
}
I want to get this request and if PHP return true, run dispatch. So I made this code
const markAsCompleted = (id) => {
console.log(toggleCompleted(id));
if (toggleCompleted(id) == 1){
toggleMarkAsCompleted(id);
}
}
toggleCompleted is a my request which is show before
toggleMarkAsCompletedis my dispatch.
If toggleCompleted return 1 I want to run my dispatch. It's simple? Interested is that this code
console.log(toggleCompleted(id));
return Test while my request 1 or 0 (from .then()). Why?

Add return in the toggleCompleted and use async/await to get return data
export const toggleCompleted = (id) => {
return axiosMethod
.get("api/taks/toggle/" + id)
.then((res) => {
console.log(res.data);
return res.data;
})
.catch((error) => {
return error;
});
};
const markAsCompleted = async (id) => {
const res = await toggleCompleted(id);
if (res == 1) {
toggleMarkAsCompleted(id);
}
};

Related

How to make two api calls using Promise.all within Angular9?

I making an api call using Promise.all as below:
Promise.all(this.hostName.slice(0, this.Id.length).map((hostName) => {
return this.serviceC.status(hostName)
.then(res => {
return new Promise((resolve, reject) => {
const oretry: ORInterface = {
oQid: res.rows[0].qid,
reason: this.reason
};
this.serviceB.retry(oretry).subscribe(resolve);
});
});
}))
.then(() => {
this.dialog.close();
})
.catch(err => {
console.log(err);
});
The above code is working fine.
Now I want to make another api call after the successful completion of this.serviceB.retry(oretry).
The second api is this.serviceB.createDbEntry(sentry) and sentry looks as below:
const sretry: SDInterface = {
hostName,
Id: this.Id.slice(0, this.Id.length),
reason: this.reason
};
And, I am doing it as below
Promise.all(this.hostName.slice(0, this.Id.length).map((hostName) => {
return this.serviceC.status(hostName)
.then(res => {
return new Promise((resolve, reject) => {
const oretry: ORInterface = {
oQid: res.rows[0].qid,
reason: this.reason
};
const sretry: SDInterface = {
hostName,
Id: this.Id.slice(0, this.Id.length),
reason: this.reason
};
this.serviceB.retry(oretry).subscribe(resolve);
this.serviceB.createDbEntry(sentry).subscribe(resolve);
});
});
}))
.then(() => {
this.dialog.close();
})
.catch(err => {
console.log(err);
});
The above code is giving an error:
error: "SequelizeValidationError: string violation: Id cannot be an array or an object"
It is looks like it is not calling the second api for every Id
You may want to take a look a forkJoin
import { Observable, forkJoin } from 'rxjs';
And then
ngOnInit() {
let one = this.http.get('some/api/1') //some observable;
let two = this.http.get('some/api/2') // another observable;
forkJoin([one, tow]).subscribe(response => {
// results[0] is our one call
// results[1] is our second call
let var1 = response[1];
let var2 = response[0];
}/*, error => { in case error handler } */);
}
Wouldn't it be better to use Promise.all() once more?
Promise.all(this.hostName.slice(0, this.Id.length).map((hostName) => {
return this.serviceC.status(hostName)
.then(res => {
return new Promise((resolve, reject) => {
const oretry: ORInterface = {
oQid: res.rows[0].qid,
reason: this.reason
};
this.serviceB.retry(oretry).subscribe(resolve);
});
})
.then(() => {
return Promise.all(this.Id.slice(0, this.Id.length).map(id => {
return new Promise((resolve, reject) => {
const sretry: SDInterface = {
hostName,
Id: id,
reason: this.reason
};
this.serviceB.createDbEntry(sentry).subscribe(resolve);
});
})
});
}))
.then(() => {
this.dialog.close();
})
.catch(err => {
console.log(err);
});
And using toPromise() will make the code more concise.
Promise.all(this.hostName.slice(0, this.Id.length).map((hostName) => {
return this.serviceC.status(hostName)
.then(res => {
const oretry: ORInterface = {
oQid: res.rows[0].qid,
reason: this.reason
};
return this.serviceB.retry(oretry).toPromise();
})
.then(() => {
return Promise.all(this.Id.slice(0, this.Id.length).map(id => {
const sretry: SDInterface = {
hostName,
Id: id,
reason: this.reason
};
this.serviceB.createDbEntry(sentry).toPromise();
})
});
}))
.then(() => {
this.dialog.close();
})
.catch(err => {
console.log(err);
});
Use combineLatest, in Angular we use RxJs not promises.
combineLatest(
[this.http.get('call1'), this.http.get('call2')]
).subscribe(([result1, result2]) => {
// do stuff with result1 and result2
});
promise.all takes input in an array and gives response in an array,
Create 2 functions each with your asynchronous logic returning a promise,
Say funcA and funcB, then use below to invoke them parellely
Promise.all([funcA(this.hostName), funcB(this.id)])
.then(respones => {
console.log(responses[0]); //return value for funcA
console.log(responses[1]); //return value for funcB
})
.catch(err => console.log(err));
I am assuming your logic of functions are correct, I just copy-pasted from your question and gave them structure
const funcA = (hostName) => {
hostName.slice(0, this.Id.length).map((hostName) => {
return this.serviceC.status(hostName)
.then(res => {
return new Promise((resolve, reject) => {
const oretry: ORInterface = {
oQid: res.rows[0].qid,
reason: this.reason
};
this.serviceB.retry(oretry).subscribe(resolve);
});
});
});
}
const funcB = (Id) => {
Id.slice(0, this.Id.length).map(id => {
return new Promise((resolve, reject) => {
const sretry: SDInterface = {
hostName,
Id: id,
reason: this.reason
};
this.serviceB.createDbEntry(sentry).subscribe(resolve);
});
})
}

How to use foreach and promise

I need to get datas with nested foreach, but I can't fill my array.
At the end of this code I would like to have an array (segId) with my datas but it is empty (because of aynschronous).
I read that I had to use Promise.all but I can't beacause my promise are nested
I'm beginner so my code is far from perfect
How can I do that ?
async function getActivities(strava, accessToken)
{
const payload = await strava.athlete.listActivities({'access_token':accessToken, 'after':'1595281514', 'per_page':'10'})
return payload;
}
async function getActivity(strava, accessToken, id)
{
const payload = await strava.activities.get({'access_token':accessToken, 'id':id, 'include_all_efforts':'true'})
return payload;
}
async function getSegment(strava, accessToken, id)
{
const payload = await strava.segments.get({'access_token':accessToken,'id':id})
return payload
}
var tableau = []
var segId = []
const activities = getActivities(strava, accessToken)
activities.then(value => {
value.forEach((element, index) => {
const activity = getActivity(strava, accessToken, element['id'])
activity.then(value => {
value['segment_efforts'].forEach((element, index) => {
const segment = getSegment(strava, accessToken, element['segment']['id'])
segment.then(value => {
segId.push(value['id'])
})
//console.log(segId)
});
});
})
}) console.log(segId)
Regards
PS : Sorry for my english ...
Something like this should work. You need to always return the inner promises to include them in your promise chain. Consider splitting the code into functions to make it more readable.
getActivities(strava, accessToken).then(activities => {
return Promise.all(activities.map(elem => {
return getActivity(strava, accessToken, elem['id']).then(activity => {
return Promise.all(activity['segment_efforts'].map(elem => {
return getSegment(strava, accessToken, elem['segment']['id']).then(segment => {
segId.push(segment['id']);
});
}));
})
}));
})
.then(_ => {
console.log(segId);
});

In JS, modify function in more university

I have a function for fetch data. But how can made this function more universal? For example, else quantity of arguments would be change.
var url = [
'http://www.json-generator.com/api/json/get/cevhxOsZnS',
'http://www.json-generator.com/api/json/get/cguaPsRxAi',
'http://www.json-generator.com/api/json/get/cfDZdmxnDm'
]
fetchData(...url)
function fetchData(a, b, c) {
var arr = [];
fetch(a)
.then(res => res.json())
.then(res => {
arr.push(res)
return fetch(b)
})
.then(res => res.json())
.then(res => {
arr.push(res)
return fetch(c)
})
.then(res => res.json())
.then(res => arr.push(res))
.then(res => console.log(arr))
}
From looking at your code, I am assuming that fetch is a function that takes an URL as input and returns a Promise.
You can make use of the fact that the arguments keyword in javascript contains all the arguments with which the function was called and make a recursive function to do what you want.
Example code for that would be like this:
var url = [
'http://www.json-generator.com/api/json/get/cevhxOsZnS',
'http://www.json-generator.com/api/json/get/cguaPsRxAi',
'http://www.json-generator.com/api/json/get/cfDZdmxnDm'
]
fetchData(...url)
function fetchData() {
var arr = [];
fetchRecursive(arguments, arr);
}
function fetchRecursive (args, arr, i = 0) {
if (i < args.length - 1) {
return fetch(args[i])
.then(res => res.json())
.then(res => {
arr.push(res);
return fetchRecursive(args[++i]);
});
} else {
return fetch(args[i])
.then(res => res.json())
.then(res => {
arr.push(res);
console.log(arr);
});
}
}
Here's another solution with a generator and async / await.
var url = [
'http://www.json-generator.com/api/json/get/cevhxOsZnS',
'http://www.json-generator.com/api/json/get/cguaPsRxAi',
'http://www.json-generator.com/api/json/get/cfDZdmxnDm'
];
function* fetchData(urls) {
var result = [];
for (someUrl of urls) {
console.log("Fetching ", someUrl);
yield new Promise((resolve) => {
fetch(someUrl).then(res => {
res.json().then(res => {
result.push(res);
resolve();
});
})
});
}
return result;
}
async function asyncCall() {
var iterator, iteration;
iterator = fetchData(url);
do {
iteration = iterator.next();
await iteration.value;
} while (!iteration.done);
console.log("done ", iteration.value);
}
asyncCall();

create function with property that can be accessed in and out of function scope

I have a function:
const fetchMovies = (function (query) {
const requestId = this.requestId(query)
return dispatch => {
dispatch(sendingRequest(requestId))
return ajax.get(`/movies/search?q=${query}`)
.then(res => {
dispatch(receievedResponse(requestId))
return dispatch(addMovies(res.data.movies))
})
}
}).bind({
requestId: (query) => `fetchMoviesLoading-${query}`
})
This allows the fetchMovies function to have the requestId able to be called within itself. However, the requestId property cannot be accessed like so:
fetchMovies.requestId === undefined // true
Is there a simple/clean way to expose the requestId?
This just looks messy:
const fetchMoviesContext = {
requestId: (query) => `fetchMoviesLoading-${query}`
}
const fetchMovies = (function (query) {
const requestId = this.requestId(query)
return dispatch => {
dispatch(sendingRequest(requestId))
return ajax.get(`/movies/search?q=${query}`)
.then(res => {
dispatch(receievedResponse(requestId))
return dispatch(addMovies(res.data.movies))
})
}
}).bind(fetchMoviesContext)
fetchMovies.requestId = fetchMoviesContext.requestId
Just use
function fetchMovies(query) {
const requestId = fetchMovies.requestId(query)
// ^^^^^^^^^^^
return dispatch => {
dispatch(sendingRequest(requestId))
return ajax.get(`/movies/search?q=${query}`)
.then(res => {
dispatch(receievedResponse(requestId))
return dispatch(addMovies(res.data.movies))
})
}
}
fetchMovies.requestId = (query) => `fetchMoviesLoading-${query}`;
Don't overcomplicate it.

react.js: Create resource with redux-form, rest api and async/await

I'm trying to create new resource with redux form and REST api.
I dispatch createPost action and I want to check if the post was succeeded before continue.
const handleFormSubmit = (values, dispatch) => {
dispatch(createPost(values));
//I want to check here if post was succeeded.
//if status = 200 this.props.history.push('/');
}
export function createPost(values) {
return async function(dispatch) {
let request;
try {
request = await axios.post(`${ROOT_URL}/posts`, values)
} catch(err) {
request = { err };
}
dispatch({
type: CREATE_POST,
payload: request
})
}
}
Return a promise, something like this :
export function createPost(values) {
return function(dispatch) {
return new Promise( async function(resolve, reject){
let request;
try {
request = await axios.post(`${ROOT_URL}/posts`, values)
} catch(err) {
reject(err)
}
dispatch({
type: CREATE_POST,
payload: request
})
resolve(request)
})
}
}
const handleFormSubmit = () => {
dispatch(createPost(values))
.then( res => {
// do yoour stuff on succes
} )
.catch(err => {
// stuff on err
})
}
As seeing your codes, I don't think you need to use promise.
Please try like following:
const getAction = (values) => (dispatch) => {
return axios
.post(`${ROOT_URL}/posts`, values)
.then(
() => {
dispatch({
type: CREATE_POST,
payload: request
})
},
() => {
throw new SubmissionError({
_error: 'Failed'
});
}
);
};
const handleSubmit = (values) => {
return dispatch(getAction(values));
};

Categories