return promise instead of xhr